Detailed explanation of request and response objects
Request Object (Request)
The Express request object (commonly referred to as req
) encapsulates the details of an HTTP request. It extends Node.js's http.IncomingMessage
object and adds Express-specific properties and methods.
Common Properties
- req.params: An object containing route parameters
app.get('/users/:userId', (req, res) => {
console.log(req.params.userId); // Get the userId parameter from the route
});
- req.query: Contains the parsed query string
// Request URL is /search?q=express&page=2
app.get('/search', (req, res) => {
console.log(req.query.q); // "express"
console.log(req.query.page); // "2"
});
- req.body: Contains request body data (requires body-parser middleware)
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/login', (req, res) => {
console.log(req.body.username); // Get the username from the POST request
});
- req.headers: Contains the request headers object
app.get('/', (req, res) => {
console.log(req.headers['user-agent']); // Get the User-Agent header
});
- req.cookies: Contains cookies sent by the client (requires cookie-parser middleware)
const cookieParser = require('cookie-parser');
app.use(cookieParser());
app.get('/', (req, res) => {
console.log(req.cookies.sessionId); // Get the cookie named sessionId
});
Common Methods
- req.get(field): Get the specified HTTP request header
const host = req.get('Host');
- req.is(type): Check if the request's Content-Type matches the given type
if (req.is('application/json')) {
// Handle JSON request
}
- req.accepts(types): Check if the client accepts the specified response type
// Client Accept: text/html,application/xhtml+xml
req.accepts('html'); // "html"
req.accepts('json'); // false
Response Object (Response)
The Express response object (commonly referred to as res
) is used to send responses to the client. It extends Node.js's http.ServerResponse
object and adds Express-specific methods.
Common Methods
- res.status(code): Set the HTTP status code
res.status(404).send('Not Found');
- res.send([body]): Send an HTTP response
res.send('Hello World'); // Send text
res.send({ user: 'tobi' }); // Send JSON
res.send('<p>some html</p>'); // Send HTML
- res.json([body]): Send a JSON response
res.json({ username: '张三' });
- res.render(view [, locals] [, callback]): Render a view template
// Using a template engine (e.g., EJS)
res.render('index', { title: 'Express' });
- res.redirect([status,] path): Redirect the request
res.redirect('/foo/bar');
res.redirect(301, 'http://example.com');
- res.set(field [, value]): Set response headers
res.set('Content-Type', 'text/plain');
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123'
});
- res.cookie(name, value [, options]): Set a cookie
res.cookie('rememberme', '1', {
maxAge: 900000,
httpOnly: true
});
- res.download(path [, filename] [, options] [, fn]): Transfer a file as an attachment
res.download('/report-12345.pdf');
res.download('/report-12345.pdf', 'report.pdf');
Chaining Response Methods
Express response methods support chaining:
res.status(201)
.set('X-Custom-Header', 'value')
.cookie('loggedIn', 'true')
.json({ success: true });
Advanced Usage of Request and Response Objects
Custom Middleware for Request Processing
You can create middleware to preprocess the request object:
app.use((req, res, next) => {
// Add custom properties
req.requestTime = new Date().toISOString();
next();
});
app.get('/', (req, res) => {
res.send(`Request received at: ${req.requestTime}`);
});
Streaming Response Handling
For large files or streaming data, you can use streaming responses:
const fs = require('fs');
app.get('/video', (req, res) => {
const videoPath = './big-video.mp4';
const stat = fs.statSync(videoPath);
const fileSize = stat.size;
const range = req.headers.range;
if (range) {
// Handle partial content requests (206 status code)
const parts = range.replace(/bytes=/, "").split("-");
const start = parseInt(parts[0], 10);
const end = parts[1] ? parseInt(parts[1], 10) : fileSize-1;
res.writeHead(206, {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': end-start+1,
'Content-Type': 'video/mp4'
});
fs.createReadStream(videoPath, {start, end}).pipe(res);
} else {
res.writeHead(200, {
'Content-Length': fileSize,
'Content-Type': 'video/mp4'
});
fs.createReadStream(videoPath).pipe(res);
}
});
Content Negotiation
Return different response formats based on the client's Accept header:
app.get('/api/user', (req, res) => {
const user = { name: '张三', age: 30 };
res.format({
'text/plain': () => {
res.send(`${user.name}, ${user.age}`);
},
'text/html': () => {
res.send(`<h1>${user.name}</h1><p>Age: ${user.age}</p>`);
},
'application/json': () => {
res.json(user);
},
default: () => {
res.status(406).send('Not Acceptable');
}
});
});
Error Handling Middleware
Use request and response objects to handle errors:
app.get('/error', (req, res, next) => {
const err = new Error('Something went wrong');
err.status = 500;
next(err);
});
// Error handling middleware
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
error: {
message: err.message,
status: err.status,
path: req.path
}
});
});
Extending Request and Response Objects
Custom Request Properties
You can extend the request object to add custom properties:
app.use((req, res, next) => {
// Add an isAuthenticated method
req.isAuthenticated = function() {
return !!req.session.userId;
};
next();
});
app.get('/profile', (req, res) => {
if (req.isAuthenticated()) {
res.send('Welcome to your profile');
} else {
res.redirect('/login');
}
});
Extending the Response Object
Similarly, you can extend the response object:
app.use((req, res, next) => {
// Add a success method
res.success = function(data) {
return this.json({
success: true,
data: data
});
};
// Add an error method
res.error = function(message, code = 400) {
return this.status(code).json({
success: false,
error: message
});
};
next();
});
app.get('/api/data', (req, res) => {
try {
const data = getSomeData();
res.success(data);
} catch (err) {
res.error(err.message);
}
});
Performance Optimization Tips
Use res.append() Instead of Multiple set Calls
// Not recommended
res.set('X-First', '1');
res.set('X-Second', '2');
// Recommended
res.append('X-First', '1');
res.append('X-Second', '2');
Use res.type() to Simplify Content-Type Setting
// Instead of
res.set('Content-Type', 'text/html');
// Use
res.type('html');
Leverage res.vary() for Cache Optimization
app.get('/content', (req, res) => {
res.vary('User-Agent').render('content');
});
Use res.location() for Safe Redirects
app.post('/login', (req, res) => {
// Validation logic...
res.location('/dashboard').status(302).end();
});
Practical Application Scenarios
File Upload Handling
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('avatar'), (req, res) => {
// req.file contains information about the uploaded file
console.log(req.file);
// req.body contains text fields
console.log(req.body);
res.send('Upload successful');
});
Implementing a RESTful API
// Get a list of resources
app.get('/api/users', (req, res) => {
const users = getUsers();
res.json(users);
});
// Get a single resource
app.get('/api/users/:id', (req, res) => {
const user = getUserById(req.params.id);
if (user) {
res.json(user);
} else {
res.status(404).json({ error: 'User not found' });
}
});
// Create a resource
app.post('/api/users', express.json(), (req, res) => {
const newUser = createUser(req.body);
res.status(201).json(newUser);
});
// Update a resource
app.put('/api/users/:id', express.json(), (req, res) => {
const updatedUser = updateUser(req.params.id, req.body);
if (updatedUser) {
res.json(updatedUser);
} else {
res.status(404).json({ error: 'User not found' });
}
});
// Delete a resource
app.delete('/api/users/:id', (req, res) => {
if (deleteUser(req.params.id)) {
res.status(204).end();
} else {
res.status(404).json({ error: 'User not found' });
}
});
WebSocket Handshake Handling
const WebSocket = require('ws');
const server = app.listen(3000);
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws, req) => {
// req is the HTTP request object
console.log('Client connected from:', req.connection.remoteAddress);
ws.on('message', (message) => {
console.log('Received:', message);
});
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:中间件机制与执行流程
下一篇:模板引擎集成与视图渲染