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