吾本为前端之工。React、Vite、Tailwind等,此乃吾之天地。而后端,向为吾所知,然鲜有触碰。今终坐而创吾首之Express服务器,欲记其事,无论初时之成败。
此非洁净之教程也。实乃吾所习、所惑、所当自诫若初学者之实录。
自零始设
首事当先:
于汝之终端运行
npm初始化之速
npm 安装 express
Then I created `server.js` and wrote the minimum possible server:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello world');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
```javascript
Run it with `node server.js`, open `http://localhost:3000` in the browser — "Hello world". That's a working HTTP server in about 10 lines.
Let me break down what each part is actually doing.
---
**Breaking down the code**
### `const express = require('express')`
This pulls the Express library from `node_modules` into the current file. `require` is CommonJS — the default module system in Node. You store it in a variable called `express`.
### `const app = express()`
You call `express()` like a function because it is one. It returns an application object — this `app` is your server's control panel. Everything attaches to it.
### The route
app.get('/', (req, res) => {
res.send('Hello world');
});
此注册一径。今当朗诵之。
"当有人发起GET请求时"/,行此函数。
req是请求之象——凡客所送者。其URL、查询参数、首部、体皆在焉。
res此应答之象——尔传物之器也。
app.listen(3000, () => { ... })
此启服务器于3000端口。回调待服务器备妥方行——故尔于其中录之,非外也。
命名请求与响应之事
吾以为req且res乃特异之钥字,以达所求。非也。不过参数之名耳。
表达则唤汝回调,以请求之对象初與應答之物second,恆如是也。名號悉由君擇:
// All of these work identically
app.get('/', (req, res) => { res.send('ok') });
app.get('/', (request, response) => { response.send('ok') });
app.get('/', (banana, mango) => { mango.send('ok') });
。末者,JavaScript有效也。mango持應答之物,.send()施於其上,無不順遂。
眾人共定req。res,俾众览君之码,立辨其异。守此成例,然知其仅为成例,则通篇之玄机顿减。
自URL中读数据
客端寄数据于GET请,有二途。
URL参数
app.get('/user/:id', (req, res) => {
id者,req之params之id也。
应答以 json,曰:{ userId: id };
});
冒号之前id道此URL之段乃变量也。故/user/jeffrey,/user/42,且/user/anything众皆趋此途。凡置于此位者,悉为所藏。req.params.id.
尔若游之:http://localhost:3000/user/jeffrey
多参数者,乃也。划破其间无逗,不隔。
app.get('/add/:a/:b', (req, res) =>{
//无误
});
app取’/add/:a,:b’之路,(req, res)应之。>{
// 错误——此非所期
});
逗号之误,耗我时日.
查询参数
app.get('/add', (req, res) => {
const a = Number(req.query.a);
const b = Number(req.query.b);
res.json({ sum: a + b });
});
汝如斯而访之。http://localhost:3000/add?a=10&b=5
何時用何
URL之参数,用以辨识特定之资源——/user/42,/product/air-max查询参数更宜于操作、筛选及可选值。/search?q=express,/add?a=10&b=5数学之运算,查询参数最为适宜。
析理为模
不欲将吾之诸函数尽书于服务器之文,乃别立一math.js:
数学之学 (math.js)
加函数(add),取二数(a,b)
返 a 与 b 之和。
}
函数乘(a, b) {
返 a * b。
}
导出模块,含加法与乘法。
Then imported it in the server:
js
// 伺服器檔案
const { 加, 乘 } = require('./數學');
This keeps the server file clean. Routes handle HTTP, modules handle logic. Good habit to build early.
---
** CommonJS vs ESModules**
Node has two module systems and I spent time going back and forth between them today.
**CommonJS:**
js
const 表達 = require('表達');
模組.exports = { 加 };
**ESModules:**
js
自 express 引之
导函数 add,以 a、b 为参,则 a 加 b 而返之
The key differences:
- To use ESM in Node, you need `"type": "module"` in your `package.json`, otherwise Node treats `.js` files as CJS by default
- ESM requires file extensions when importing local files: `./math.js` not `./math`
- You cannot mix them freely. `require` in an ESM file breaks. `import` in a CJS file breaks.
**My recommendation if you're just starting:** stick with CommonJS. No config needed, works out of the box, and the vast majority of Express tutorials and packages are written in it. Switch to ESM when you have a concrete reason to.
---
## Handling POST requests
GET requests carry data in the URL. POST requests carry data in the **body** — like submitting a login form or hitting an API with JSON. You don't want a password showing up in someone's browser history.
js
使 app 以 post 之於 /login,以 (req, res) 为之> {
诸 username、password 於 req.body 中取之
賜以文,曰:Welcome ${username};
而終之。
But there's a catch. To read `req.body`, you need this line **before** your routes:
言:
`app.use()` applies middleware to every incoming request. `express.json()` reads the raw request body and parses it as JSON so you can access it via `req.body`.
I removed this line to see what would happen. Got this:
析构之属'username'于'req.body'不可,盖其未定义也.
Without it, `req.body` is just `undefined`. The middleware is not optional — and it must come before your routes, not after.
To test POST requests, you can't use the browser URL bar. Use **Thunder Client** (VS Code extension) or Postman. Send a POST to `http://localhost:3000/login` with this JSON body:
json
{
"username": "jeffrey",
"password": "velto123"
}
Response:
json
{
"message": "Welcome jeffrey"
}
微物之惑我神明也
一、听回调之惑
// Wrong — logs before the server is ready
app.listen(3000, console.log("Server running on port 3000"));
// Right — logs once the server is actually up
app.listen(3000, () => console.log("Server running on port 3000"));
无箭头函数者console.log 载文件时立时执行,非俟服务器备妥。此别虽微,实有关键。
2. res.send() 與 res.json()
res.send() 乃用于平文。res.json() 乃用于物象与结构之数据。尔建 API 时,几欲 res.json()。
3. 不重启服务器
每改之,辄思何故无殊——旧服务器犹在运行。一蹴而就之。
node --watch server.js
内置于Node 18以上版本,无需安装。每有文件变动,服务器自动重启。
吾所至之处
会毕,已得Express服务器之可用者,具:
- 自URL之参数及查询参数中取道途
- 别置算术之模,具
add与mult之能 - 一POST之途,取自
req.body - 一固之心,明乎众事之合契
尔为前端之工,若如吾昔避Express,则此道实非远矣。其理与尔所习者暗合。路由者,犹若事件之听者。中件者,乃于处理之前而运行之函数。req与res者,亦不过为物象耳。
始于一得之路由。破之,则此理自固。
吾乃 Chinwuba Jeffrey,Velto 之首席运营官,此乃专精非洲市场之高级网页设计所。吾正记录其全栈之途。若汝亦循此道,可随吾同行。












