Request对象 #
一、Request对象概述 #
1.1 什么是Request对象? #
Request对象(通常简写为req)代表了HTTP请求。它包含了请求的所有信息,如请求参数、请求头、请求体等。
1.2 基本结构 #
javascript
app.get('/', (req, res) => {
console.log(req.method);
console.log(req.url);
console.log(req.headers);
console.log(req.body);
console.log(req.query);
console.log(req.params);
});
二、请求属性 #
2.1 基本属性 #
| 属性 | 说明 |
|---|---|
| req.method | HTTP方法 |
| req.url | 请求URL路径 |
| req.originalUrl | 原始请求URL |
| req.path | URL路径部分 |
| req.hostname | 主机名 |
| req.ip | 客户端IP地址 |
| req.protocol | 协议(http/https) |
| req.secure | 是否HTTPS |
| req.xhr | 是否AJAX请求 |
2.2 使用示例 #
javascript
app.get('/info', (req, res) => {
res.json({
method: req.method,
url: req.url,
originalUrl: req.originalUrl,
path: req.path,
hostname: req.hostname,
ip: req.ip,
protocol: req.protocol,
secure: req.secure,
xhr: req.xhr
});
});
2.3 获取客户端信息 #
javascript
app.use((req, res, next) => {
req.clientInfo = {
ip: req.ip || req.connection.remoteAddress,
userAgent: req.headers['user-agent'],
referer: req.headers.referer || req.headers.referrer,
language: req.headers['accept-language']
};
next();
});
app.get('/client', (req, res) => {
res.json(req.clientInfo);
});
三、请求参数 #
3.1 路径参数(req.params) #
javascript
app.get('/users/:id', (req, res) => {
res.json({ userId: req.params.id });
});
app.get('/posts/:postId/comments/:commentId', (req, res) => {
res.json({
postId: req.params.postId,
commentId: req.params.commentId
});
});
3.2 查询参数(req.query) #
javascript
app.get('/search', (req, res) => {
const { q, page, limit, sort } = req.query;
res.json({ q, page, limit, sort });
});
访问 /search?q=express&page=1&limit=10&sort=desc:
json
{
"q": "express",
"page": "1",
"limit": "10",
"sort": "desc"
}
3.3 请求体(req.body) #
需要先使用中间件解析:
javascript
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post('/users', (req, res) => {
res.json(req.body);
});
3.4 参数类型转换 #
javascript
app.get('/products', (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const minPrice = req.query.minPrice ? parseFloat(req.query.minPrice) : null;
const inStock = req.query.inStock === 'true';
res.json({ page, limit, minPrice, inStock });
});
四、请求头 #
4.1 获取请求头 #
javascript
app.get('/headers', (req, res) => {
res.json({
all: req.headers,
contentType: req.headers['content-type'],
userAgent: req.headers['user-agent'],
authorization: req.headers['authorization'],
accept: req.headers.accept
});
});
4.2 常用请求头 #
| 请求头 | 说明 |
|---|---|
| content-type | 内容类型 |
| authorization | 认证信息 |
| user-agent | 用户代理 |
| accept | 接受的内容类型 |
| accept-language | 接受的语言 |
| cache-control | 缓存控制 |
| cookie | Cookie信息 |
4.3 Content-Type判断 #
javascript
app.post('/data', (req, res) => {
const contentType = req.headers['content-type'];
if (contentType?.includes('application/json')) {
res.json({ type: 'JSON', data: req.body });
} else if (contentType?.includes('multipart/form-data')) {
res.json({ type: 'FormData' });
} else if (contentType?.includes('application/x-www-form-urlencoded')) {
res.json({ type: 'URL Encoded', data: req.body });
} else {
res.status(415).json({ error: '不支持的媒体类型' });
}
});
4.4 Authorization解析 #
javascript
app.get('/protected', (req, res) => {
const authHeader = req.headers['authorization'];
if (!authHeader) {
return res.status(401).json({ error: '缺少认证信息' });
}
const [type, token] = authHeader.split(' ');
if (type.toLowerCase() !== 'bearer') {
return res.status(401).json({ error: '不支持的认证类型' });
}
res.json({ token });
});
五、Cookie #
5.1 使用cookie-parser #
bash
npm install cookie-parser
javascript
const cookieParser = require('cookie-parser');
app.use(cookieParser());
app.get('/cookies', (req, res) => {
res.json({
cookies: req.cookies,
signedCookies: req.signedCookies
});
});
5.2 设置和读取Cookie #
javascript
app.get('/set-cookie', (req, res) => {
res.cookie('name', 'express', {
maxAge: 900000,
httpOnly: true,
secure: true,
signed: true
});
res.json({ message: 'Cookie已设置' });
});
app.get('/get-cookie', (req, res) => {
res.json({
name: req.cookies.name,
signedName: req.signedCookies.name
});
});
六、Session #
6.1 使用express-session #
bash
npm install express-session
javascript
const session = require('express-session');
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: { maxAge: 60000 }
}));
app.get('/login', (req, res) => {
req.session.userId = 1;
req.session.username = 'admin';
res.json({ message: '已登录' });
});
app.get('/profile', (req, res) => {
if (!req.session.userId) {
return res.status(401).json({ error: '请先登录' });
}
res.json({
userId: req.session.userId,
username: req.session.username
});
});
app.get('/logout', (req, res) => {
req.session.destroy();
res.json({ message: '已退出' });
});
七、文件上传 #
7.1 使用multer #
javascript
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('file'), (req, res) => {
res.json({
file: req.file,
body: req.body
});
});
app.post('/photos', upload.array('photos', 5), (req, res) => {
res.json({
files: req.files,
body: req.body
});
});
7.2 req.file属性 #
javascript
app.post('/upload', upload.single('avatar'), (req, res) => {
const { file } = req;
res.json({
fieldname: file.fieldname,
originalname: file.originalname,
encoding: file.encoding,
mimetype: file.mimetype,
size: file.size,
destination: file.destination,
filename: file.filename,
path: file.path
});
});
八、请求范围 #
8.1 Range请求 #
javascript
app.get('/video', (req, res) => {
const range = req.headers.range;
if (!range) {
return res.status(400).send('需要Range头');
}
const videoSize = fs.statSync('video.mp4').size;
const CHUNK_SIZE = 10 ** 6;
const start = Number(range.replace(/\D/g, ''));
const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
const contentLength = end - start + 1;
const headers = {
'Content-Range': `bytes ${start}-${end}/${videoSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': contentLength,
'Content-Type': 'video/mp4'
};
res.writeHead(206, headers);
const videoStream = fs.createReadStream('video.mp4', { start, end });
videoStream.pipe(res);
});
九、请求扩展 #
9.1 添加自定义属性 #
javascript
app.use((req, res, next) => {
req.requestTime = new Date().toISOString();
req.id = generateRequestId();
next();
});
app.get('/', (req, res) => {
res.json({
requestId: req.id,
requestTime: req.requestTime
});
});
9.2 用户信息注入 #
javascript
const jwt = require('jsonwebtoken');
app.use((req, res, next) => {
const token = req.headers['authorization']?.split(' ')[1];
if (token) {
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
} catch (error) {
req.user = null;
}
}
next();
});
app.get('/profile', (req, res) => {
if (!req.user) {
return res.status(401).json({ error: '请先登录' });
}
res.json(req.user);
});
十、常用方法 #
10.1 req.get() #
获取请求头:
javascript
app.get('/', (req, res) => {
const contentType = req.get('Content-Type');
const userAgent = req.get('User-Agent');
res.json({ contentType, userAgent });
});
10.2 req.is() #
检查Content-Type:
javascript
app.post('/data', (req, res) => {
if (req.is('json')) {
res.json({ type: 'JSON' });
} else if (req.is('urlencoded')) {
res.json({ type: 'URL Encoded' });
} else {
res.status(415).json({ error: '不支持的媒体类型' });
}
});
10.3 req.accepts() #
检查Accept头:
javascript
app.get('/', (req, res) => {
const accept = req.accepts(['json', 'html', 'text']);
switch (accept) {
case 'json':
res.json({ message: 'Hello' });
break;
case 'html':
res.send('<h1>Hello</h1>');
break;
default:
res.send('Hello');
}
});
10.4 req.acceptsCharsets() #
javascript
app.get('/', (req, res) => {
const charset = req.acceptsCharsets(['utf-8', 'iso-8859-1']);
res.set('Content-Type', `text/plain; charset=${charset}`);
res.send('Hello');
});
10.5 req.acceptsLanguages() #
javascript
app.get('/', (req, res) => {
const lang = req.acceptsLanguages(['zh-CN', 'en-US', 'ja']);
res.json({ language: lang });
});
十一、完整示例 #
javascript
const express = require('express');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const multer = require('multer');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: false
}));
const upload = multer({ dest: 'uploads/' });
app.use((req, res, next) => {
req.requestTime = new Date().toISOString();
next();
});
app.get('/info', (req, res) => {
res.json({
method: req.method,
url: req.originalUrl,
path: req.path,
query: req.query,
headers: {
'content-type': req.headers['content-type'],
'user-agent': req.headers['user-agent'],
'authorization': req.headers['authorization']
},
cookies: req.cookies,
session: req.session,
ip: req.ip,
requestTime: req.requestTime
});
});
app.get('/users/:id', (req, res) => {
res.json({
params: req.params,
userId: req.params.id
});
});
app.post('/users', (req, res) => {
res.status(201).json({
body: req.body,
requestTime: req.requestTime
});
});
app.post('/upload', upload.single('file'), (req, res) => {
res.json({
file: req.file,
body: req.body
});
});
app.listen(3000);
十二、总结 #
Request对象要点:
| 属性/方法 | 说明 |
|---|---|
| req.params | 路径参数 |
| req.query | 查询参数 |
| req.body | 请求体 |
| req.headers | 请求头 |
| req.cookies | Cookie |
| req.session | 会话 |
| req.file | 上传文件 |
| req.get() | 获取请求头 |
| req.is() | 检查Content-Type |
| req.accepts() | 检查Accept |
下一步,让我们学习Response对象!
最后更新:2026-03-28