第7章 Web 开发
- 理解 HTTP 协议概念
- 掌握 http 模块的基本使用
HTTP是一种能够获取如 HTML 这样的网络资源的** (通讯协议)。它是在 Web 上进行数据交换的基础,是一种 client-server 协议,也就是说,请求通常是由像浏览器这样的接受方发起的。一个完整的Web文档通常是由不同的子文档拼接而成的,像是文本、布局描述、图片、视频、脚本等等。
HTTP 消息报文
HTTP消息是服务器和客户端之间交换数据的方式。有两种类型的消息︰
- 请求—由客户端发送用来触发一个服务器上的动作
- 响应—来自服务器的应答。
HTTP消息由采用ASCII编码的多行文本构成。在HTTP/1.1及早期版本中,这些消息通过连接公开地发送。在HTTP/2中,为了优化和性能方面的改进,曾经可人工阅读的消息被分到多个HTTP帧中。
Web 开发人员或网站管理员,很少自己手工创建这些原始的HTTP消息︰ 由软件、浏览器、 代理或 服务器完成。他们通过配置文件(用于代理服务器或服务器),API (用于浏览器)或其他接口提供HTTP消息。
HTTP 请求和响应具有相似的结构,由以下部分组成︰
- 一行起始行用于描述要执行的请求,或者是对应的状态,成功或失败。这个起始行总是单行的。
- 一个可选的HTTP头集合指明请求或描述消息正文。
- 一个空行指示所有关于请求的元数据已经发送完毕。
- 一个可选的包含请求相关数据的正文 (比如HTML表单内容), 或者响应相关的文档。 正文的大小有起始行的HTTP头来指定。
起始行和 HTTP 消息中的HTTP 头统称为请求头,而其有效负载被称为消息正文。
请求报文
请求由以下元素组成:
- 一个HTTP的method,经常是由一个动词像,
POST
或者一个名词像,HEAD
来定义客户端的动作行为。通常客户端的操作都是获取资源(GET方法)或者发送表单值(POST方法),虽然在一些情况下也会有其他操作。 - 要获取的资源的路径,通常是上下文中就很明显的元素资源的URL,它没有protocol(
http://
),(developer.mozilla.org
),或是TCP的port(HTTP一般在80端口)。 - HTTP协议版本号。
- 为服务端表达其他信息的可选头部。
- 对于一些像POST这样的方法,报文的body就包含了发送的资源,这与响应报文的body类似。
起始行
一个 HTTP 方法,一个动词 (像
GET
, 或者POST
) 或者一个名词 (像 或者OPTIONS
), 描述要执行的动作. 例如,GET
表示要获取资源,POST
表示向服务器推送数据 (创建或修改资源, 或者产生要返回的临时文件)。请求目标 (request target),
通常是一个URL,或者是协议、端口和域名的绝对路径,通常以请求的环境为特征。请求的格式因不同的 HTTP 方法而异。它可以是:
- 一个绝对路径,末尾跟上一个 ‘ ? ‘ 和查询字符串。这是最常见的形式,称为 原始形式 (origin form),被 GET,POST,HEAD 和 OPTIONS 方法所使用。
POST / HTTP 1.1GET /background.png HTTP/1.0HEAD /test.html?query=alibaba HTTP/1.1OPTIONS /anypage.html HTTP/1.0
- 一个完整的URL,被称为 绝对形式 (absolute form),主要在 GET 连接到代理时使用。
GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
- 由域名和可选端口(以
':'
为前缀)组成的 URL 的 authority component,称为 authority form。 仅在使用 CONNECT 建立 HTTP 隧道时才使用。 - 星号形式 (asterisk form),一个简单的星号
('*')
,配合 OPTIONS 方法使用,代表整个服务器。OPTIONS * HTTP/1.1
- 一个绝对路径,末尾跟上一个 ‘ ? ‘ 和查询字符串。这是最常见的形式,称为 原始形式 (origin form),被 GET,POST,HEAD 和 OPTIONS 方法所使用。
HTTP 版本 (HTTP version),定义了剩余报文的结构,作为对期望的响应版本的指示符。
Headers
来自请求的 遵循和 HTTP header 相同的基本结构:不区分大小写的字符串,紧跟着的冒号 (':')
和一个结构取决于 header 的值。 整个 header(包括值)由一行组成,这一行可以相当长。
有许多请求头可用,它们可以分为几组:
- General headers,例如
Via
,适用于整个报文。 - Request headers,例如 ,
Accept-Type
,通过进一步的定义(例如 ),或者给定上下文(例如Referer
),或者进行有条件的限制 (例如 ) 来修改请求。 - Entity headers,例如
Content-Length
,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
Body
请求的最后一部分是它的 body。不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。
Body 大致可分为两类:
- Single-resource bodies,由一个单文件组成。该类型 body 由两个 header 定义: 和
Content-Length
. - ,由多部分 body 组成,每一部分包含不同的信息位。通常是和 HTML Forms 连系在一起。
响应报文包含了下面的元素:
- 一个状态码(),来告知对应请求执行成功或失败,以及失败的原因。
- 一个状态信息,这个信息是非权威的状态码描述信息,可以由服务端自行设定。
- HTTP headers,与请求头部类似。
- 可选项,比起请求报文,响应报文中更常见地包含获取的资源body。
状态行
HTTP 响应的起始行被称作 状态行 (status line),包含以下信息:
- 协议版本,通常为
HTTP/1.1。
- 状态码 (**status code),表明请求是成功或失败。常见的状态码是 ,
404
,或 。 - 状态文本 (status text)。一个简短的,纯粹的信息,通过状态码的文本描述,帮助人们理解该 HTTP 消息。
Headers
响应的 HTTP headers 遵循和任何其它 header 相同的结构:不区分大小写的字符串,紧跟着的冒号 (':'
) 和一个结构取决于 header 类型的值。 整个 header(包括其值)表现为单行形式。
有许多响应头可用,这些响应头可以分为几组:
- General headers,例如 ,适用于整个报文。
- Response headers,例如
Vary
和 ,提供其它不符合状态行的关于服务器的信息。 - Entity headers,例如
Content-Length
,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
Body
响应的最后一部分是 body。不是所有的响应都有 body:具有状态码 (如 或 204
) 的响应,通常不会有 body。
Body 大致可分为三类:
- Single-resource bodies,由已知长度的单个文件组成。该类型 body 由两个 header 定义: 和
Content-Length
。 - Single-resource bodies,由未知长度的单个文件组成,通过将 设置为
chunked 来
使用 chunks 编码。 - Multiple-resource bodies,由多部分 body 组成,每部分包含不同的信息段。但这是比较少见的。
请求方法
参考资料:
返回结果的HTTP状态码
1xx 临时响应
状态码 | 说明 |
---|---|
100 | 继续,请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分 |
101 | 切换协议,请求者已要求服务器切换协议,服务器已确认并准备切换 |
2xx 成功
表示成功处理了请求的状态代码
3xx 重定向
状态码 | 说明 |
---|---|
301 | 永久移动,请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置 |
302 | 临时移动,服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求 |
304 | 未修改,自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容 |
307 | 临时重定向,服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求 |
4xx 请求错误
表示请求可能出错,妨碍了服务器的处理
5xx 服务器错误
状态码 | 说明 |
---|---|
500 | (服务器内部错误) 服务器遇到错误,无法完成请求。 |
501 | (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 |
502 | (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 |
503 | (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 |
504 | (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。 |
505 | (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。 |
参考链接:
电话打通,没有响应
很傻的服务器
网站中的资源都是通过 url
地址来定位的,所以我就可以在请求处理函数获取客户端的请求地址,然后根据不同的请求地址处理不同的响应。
解决中文乱码问题
Content-Type
- 根据不同的内容类型所对应的数据也不一样,具体查询:
- html 文件中的
<meta charset="UTF-8" />
- html 文件需要如果声明了 meta-charset 则可以不写 Content-Type
- 建议每个响应都告诉客户端我给你发送的 Content-Type 内容类型是什么
处理页面中的多个请求
API 总结
请求对象 Request
- url
- method
响应对象 Response
- write
- end
留言本案例
- 自己处理静态资源
- 处理表单提交
- 列表查询
- 表单提交