目标:熟悉请求对象 req
身上的一些常见成员
请求对象中记录的内容主要是客户端的一些信息,当我们想要获取请求客户端的相关信息时,不妨将整个 req 请求对象给打印出来,然后到里边去找我们需要的部分。
没必要去刻意记忆 req 对象身上都有哪些成员,对于常用的一些成员,用久了自然也就记住了。
源码:req.zip
参考资料:
请求对象(req)
在 Express 中,请求对象(通常表示为 req
)和响应对象(通常表示为 res
)是处理 HTTP 请求和响应的关键组件。它们分别基于 Node.js 原生的 http.IncomingMessage
和 http.ServerResponse
对象,但提供了更多有用的方法和属性。
请求对象表示客户端(如浏览器或其他客户端应用程序)发出的 HTTP 请求。它包含了与请求相关的信息,如 URL、HTTP 方法、请求头、查询参数等。一些常见的 req
属性和方法包括:
req.method
:HTTP 请求方法(例如 “GET”、”POST” 等)。req.url
或req.originalUrl
:请求的 URL。req.path
:请求的路径(不包含查询字符串)。req.query
:一个对象,包含请求的查询参数。req.headers
:一个对象,包含请求的 HTTP 头信息。req.params
:一个对象,包含路由参数(当使用参数化路由时)。req.body
:一个对象,包含请求的主体数据(需要使用 body-parser 中间件)。
demo
认识请求对象 req,知道它身上都有哪些信息。
const express = require('express');
const app = express();
const port = 3000;
// 添加一个中间件来解析 JSON 格式的请求体(仅用于演示 req.body)
app.use(express.json());
// 中间件:记录请求日志
app.use((req, res, next) => {
console.log(`[${new Date().toLocaleString()}] ${req.method} ${req.url}`);
next();
});
app.get('/users/:userId', (req, res) => {
console.log('Request method:', req.method);
console.log('Request path:', req.path);
console.log('Query parameters:', req.query);
console.log('Route parameters:', req.params);
console.log('Request URL:', req.url);
console.log('Request headers:', req.headers);
console.log('Request body:', req.body);
console.log('Request cookies:', req.cookies);
console.log('Request IP:', req.ip);
console.log('Request protocol:', req.protocol);
console.log('Request hostname:', req.hostname);
res.send(`User ID: ${req.params.userId}`);
});
// 启动服务器
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
在这个示例中,当您访问 http://localhost:3000/users/123?a=1&b=2#sadf 时,服务器会在控制台输出如下信息:
huyouda@HuyoudeMacBook-Pro 230510_req % node 1.js
Server running at http://localhost:3000
[2023/5/10 22:23:14] GET /users/123?a=1&b=2
Request method: GET
Request path: /users/123
Query parameters: { a: '1', b: '2' }
Route parameters: { userId: '123' }
Request URL: /users/123?a=1&b=2
Request headers: {
host: 'localhost:3000',
connection: 'keep-alive',
'sec-ch-ua': '"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
'if-none-match': 'W/"c-pljREVPO5rx9tAupmIu0P2XWUm4"'
}
Request body: {}
Request cookies: undefined
Request IP: ::1
Request protocol: http
Request hostname: localhost
这些请求头字段包含了客户端和服务器之间通信时的元信息。以下是这些请求头字段的简要说明:
host
: 请求的目标主机和端口,例如 “localhost:3000”。connection
: 控制网络连接的持续性。”keep-alive” 表示使用长连接,以减少后续请求的建立连接时间。sec-ch-ua
: 提供浏览器品牌和版本信息。这有助于服务器识别客户端类型并针对不同浏览器做出适当调整。sec-ch-ua-mobile
: 指示设备是否为移动设备。”?0” 表示设备不是移动设备,”?1” 表示设备是移动设备。sec-ch-ua-platform
: 提供客户端操作系统信息。这可以帮助服务器针对特定平台进行优化。upgrade-insecure-requests
: 表示浏览器支持将不安全的 HTTP 请求升级为 HTTPS。user-agent
: 包含客户端浏览器、操作系统和其他环境信息的字符串。服务器可以根据该信息提供特定于用户代理的内容。accept
: 描述客户端接受的 MIME 类型。服务器可以根据此信息返回适当格式的响应。sec-fetch-site
: 描述请求的来源站点关系,如 “same-origin”、”cross-site” 或 “none”。有助于实现跨站点请求的安全策略。sec-fetch-mode
: 描述请求的模式,如 “navigate”、”same-origin”、”no-cors” 等。这有助于服务器实施安全策略。sec-fetch-user
: 表示用户是否有意发起此请求,”?1” 表示用户有意发起请求,”?0” 表示无意发起请求。sec-fetch-dest
: 描述请求的目的地类型,如 “document”、”style” 等。这可以帮助服务器做出适当的响应。accept-encoding
: 描述客户端支持的压缩算法,如 “gzip”、”deflate”、”br” 等。服务器可以根据此信息返回经过适当压缩的响应。accept-language
: 描述客户端接受的自然语言。服务器可以根据此信息返回适当语言的响应。if-none-match
: 用于缓存验证。服务器可以根据此标头确定客户端缓存的内容是否过期,从而决定是否返回新内容或 304 Not Modified 响应。
了解这些请求头字段有助于我们更好地理解客户端和服务器之间的交互,以便为用户提供更好的服务。
注意:
#sadf
URL 中的哈希片段不会发送到服务器,因此无法在服务器端获取req.body
在 GET 请求中通常为空,因为 GET 请求不包含请求体
补充
思考:为什么 URL 的 哈希(hash) 部分不会发送给服务端呢?
答:hash 部分,通常仅在客户端会有点儿用,即便丢给服务端,基本也是没啥用的。
哈希部分(URL 中的 #
及其后的内容,例如 #sadf
)在浏览器中被称为 “URL fragment”(URL 片段)。根据 HTTP 协议和浏览器的实现,URL 片段不会发送到服务器。URL 片段主要用于以下几个目的:
- 页面内导航:URL 片段可以在不向服务器发送请求的情况下,实现页面内导航。例如,在一个较长的网页中,使用 URL 片段可以直接定位到页面的某个部分。这些片段通常与 HTML 锚点元素(如
<a id="section1"></a>
)相关联。 - 客户端状态:URL 片段还可以用于在浏览器中存储客户端状态,例如,表示某个 UI 元素的展开或折叠状态。这样的信息仅在客户端上下文中有意义,因此无需将其发送到服务器。
- 单页应用(SPA)的客户端路由:在单页应用中,URL 片段通常用于表示客户端路由。这样可以在不重新加载整个页面的情况下,实现内容的动态加载和显示。在这种情况下,客户端 JavaScript 代码会解析 URL 片段,并根据其值来显示相应的内容。
由于这些用途通常与服务器端处理无关,因此浏览器不会将 URL 片段发送到服务器。这可以提高网络传输效率,并确保服务器端处理的关注点与客户端 UI 或状态无关。
http 请求头信息
当我们通过浏览器地址栏发起请求时,浏览器会自动设置一些请求头信息。这些请求头信息用于向服务器提供关于客户端(浏览器)和请求的上下文信息。以下是一些常见请求头及其用途的简要说明:
host
:指定请求的目标主机和端口。这对于虚拟主机的情况特别有用,因为同一服务器上可能托管了多个网站,服务器需要根据此头信息来识别要访问哪个网站。connection
:指示网络连接的首选项,例如keep-alive
通知服务器在发送响应后保持连接,以便进一步重用。sec-ch-ua
和sec-ch-ua-platform
:提供浏览器和操作系统的信息。这有助于服务器根据客户端的特性来定制响应。upgrade-insecure-requests
:告诉服务器,客户端希望将不安全的请求(如 HTTP)升级为安全的请求(如 HTTPS)。user-agent
:提供有关客户端浏览器、操作系统和设备的详细信息。这可以帮助服务器为不同设备提供适当的内容。accept
:描述客户端接受的内容类型。这可以帮助服务器确定要发送哪种类型的响应。sec-fetch-site
、sec-fetch-mode
、sec-fetch-user
、sec-fetch-dest
:提供有关请求来源、模式、用户交互和目标的安全上下文信息。这有助于服务器执行安全策略。accept-encoding
:描述客户端支持的压缩算法,如gzip
、deflate
和br
。这允许服务器选择合适的压缩方式以减小响应体的大小。accept-language
:指示客户端首选的语言。这可以帮助服务器为用户提供适当的本地化内容。cookie
:包含与服务器之前交互时设置的 Cookie。服务器可以根据这些 Cookie 来识别用户状态或执行其他功能。
这些请求头信息由浏览器自动生成,并在发起请求时附加到请求中。有关 HTTP 请求头的更多信息,您可以参考 MDN 文档。