第二章 收信、回信
读短信
收到前端发来的请求时,后端首先要做的,就是读请求:
- 请求的方法(比如
GET
、POST
、PUT
、DELETE
……) - 请求的路径(比如
/user
、/user?id=2
、/book
、/book/2
……) - 其他参数(比如“用于身份验证的 token”、“使用的 http 协议版本号”……)
不用解释吧,js 写后端就是这么简单直接。
我想你已经注意到了,上面的
req
和res
对象分别代表 request(请求)和 response(响应)。 如果你想读取前端发来的数据,就去req
里找;想返回数据给前端,就使用res
。
读路径里的参数
前端向后端发消息,一种重要的载体,就是路径:把参数放路径里。
像 /user?name=PPz&year=3
,这个路径里就包含了 name
和 year
参数。
在 Node.js
,这样读:
注意点 一
在浏览器环境(前端环境)里,也有 URL 这个全局构造器。
不太熟悉的同学,要查一查、搜一搜了。
Node.js
里的 URL 和浏览器里的 URL 是一样的。
其中的 url.searchParams
是一个 URLSearchParams
对象,浏览器环境里当然也有。
注意点 二
下面两种代码,发出的请求是一样的(所以解析方法也一样):
注意点 三
很多时候,前端上传的数据,不仅量大,而且结构复杂。比如:
这种情况下,数据通常会以“附件”的形式,发给后端。解析 “附件” 比较复杂,这会在下下一章讨论。
回短信
要注意:“回”短信,是回复。在 http 通信中,后端只能回复。 没有请求时,后端就在那等着,啥也不干。 就像前端里,添加点击事件后,只要用户不点按钮,监听器里的代码永远不会执行。
扩展阅读(可以跳过)
websocket
可以实现后端“主动”发消息。 但前提是,前端要事先主动发起连接、建立连接,这之后,后端才能“主动”发消息。websocket
不在此小教程讨论范围内。
之前的例子中,都回复一个字符串。当然也可以回复 json:
可以看到,第 22 行,依然是回复一个字符串。 只不过,是把一个对象,先转化成 json 格式的字符串,然后响应。 实际上,其他编程语言、后端框架,在响应 json 时,也是一样的,并不存在什么“高级的东西”。
而第 16 行,是告诉客户端(前端):响应数据的格式(即 “content(内容) type(类型)是 json”)。
这里看起来有点奇怪:一般情况下,后端的同事,都是口头或文档告诉前端 “响应的格式是什么”,为什么要写在代码里?
这是因为,像 aioxs 这样库,在收到后端的回信(响应)后,会自动读取 header 里的 Content-Type
字段,如果发现是 application/json
,
就会帮我们解析好(用 JSON.parse
)。
但如果前端直接用浏览器内置的 fetch api,因为 fetch 没有自动解析的功能,
所以 Content-Type
就没必要设置了。
可以用 Postman 试一下,设不设置
Content-Type
有什么区别。(注意:改了代码后,记得重启项目)
小结
如果一口气看了三章,那么建议动手敲一敲代码、探索探索,然后休息休息。
应了解:
- 读请求里的 method、url(包括 path 和 路径参数)、headers
- Content-Type(非必要)
- 响应 json
练习查询文档
以下内容,可以跳过
就我个人而言,一直使用的学习方法是(分两步): 第一步:先了解概念、流程,大致了解学的东西是什么、有哪些操作。 相比于“大教程”,这只占用很少的时间。
但细节,在“小教程”里是学不到的。 但是的但是,在“大教程”里真能学到“细节”? 虽然大教程里,会介绍细节,但细节之所以称为细节,就是因为细节多、难记。 除非你经常使用,否则,仅在教程里看一眼、听一句,其实是过目就忘。
所以,我学习时,第二步,也就是“了解大概”之后, 会去尝试使用它,遇到问题就查文档,或直接用搜索引擎。
比如 req
和 res
对象的官方文档:
- req: http.IncomingMessage
- res: http.ServerResponse
文档里的内容非常非常多,我们只需要根据目录,找我们想知道的就可以了。