Mather

We create our own demons.

HTTP 协议小结

默认分类 0 评

HTTP 协议的产生就是被设计用于 Web 浏览器和服务器之间的通信,也直接基于 TCP/IP 协议,这保证传输时比 UDP 可靠。同时还有以下优点

  • 简单
  • 可扩展
  • 无状态
sequenceDiagram
客户端->>服务器: 请求 (Requst)
服务器->>客户端: 响应 (Response)

由像浏览器这样的客户端发出的消息叫做 Requsts,被服务端回应的消息叫做 Responses。

从百度开始,当我们敲下回车键时,浏览器就发出了一条请求:

GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

Chrome 在请求时,使用了 GET 方法来获取在 www.baidu.com 上的资源,没有强制的地写成 http://www.baidu.com:80,并告诉服务当前协议是 1.1 版本。

Host 的 Host: www.baidu.com 正好和 GET 后面的 / 组成 www.baidu.com/ ,如果请求该主机下的其他目录,这个位置也会有相应的变化。

使用 wireshark 可以捕获这个请求,但最直观方法是打开 Chrome Network 面板来查看

image

在请求头总还有一些字段,

User-Agent 虽然能判断客户端的版本和一些信息,显得非常糟糕的是,它经常在业务上被用来区别和提供不同的页面或者服务。

Accept 客户端告诉服务器可以处理的内容类型,通常这里会用 MIME 类型来表示;反过来,服务器通过响应头中的 Content-Type 来告诉客户端它返回内容的类型。

当服务器收到这个请求时候,经由 Nginx 或 Apache 响应之后,可能还会经过 PHP 或 Java 语言做数据存取处理,最终响应回到了客户端

HTTP/1.1 302 Found
Connection: Keep-Alive
Content-Length: 225
Content-Type: text/html
Date: Sun, 02 Sep 2018 03:57:06 GMT
Location: https://www.baidu.com/
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Server: BWS/1.1
Set-Cookie: BAIDUID=C267DF134F37696F3274F4649989CCD4:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=C267DF134F37696F3274F4649989CCD4; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1535860626; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BD_LAST_QID=13976029323002

常规 General

Request Method , 根据数据流动的方向和交互,HTTP 请求类型分为好几种类型

Request Method常用场景
GET获取 HTML CSS JS 图片等资源文件,也用于文本数据(JSON、XML)的获取
OPTIONS询问服务器某个资源支持的 Request Method ,返回头中会有 Allow 或者 Access-Control-Allow-Methods。发起跨域请求时,一些应用框架会发起该请求
POST发送数据给服务器常用的方法,在数据提交时和跨域请求场景下变得复杂

请求 Requst

客户端发出请求时,不论上述的 GET/POST 还是其他方式,下面的请求头都有可能出现:

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

发送数据给服务器常用的方法,需指定请求头中的 Content-Type 来告诉服务器发送内容的实际编码类型,与后端进行数据交换时,需要提前约定好数据类型及结构,这样能高效地推进项目进度。在表单提交和资源上传时尤为重要;

Content-Type说明
text/html; charset=UTF-8还记得我们编写 HTML 时候首先就是声明了文档类型: <!DOCTYPE html> <meta charset="UTF-8"> 也在这里得到了体现
text/cssCSS 样式文件
application/javascriptJavaScript 文件
image/pngpng 图片资源文件
application/x-www-form-urlencoded请求实体中的数据内容类型以 urldecode 方式带上,GET 时将 encode 后的字符作为 URL 的查询参数https://92yo6ypwz4.codesandbox.io/abc?aa=111&bb=222;POST 时 encode 内容存在于实体中(表单提交 )aa=111&bb=222
application/json;charset=UTF-8告诉服务端请求实体 POST 中带上的数据内容类型为 JSON

响应头中也存在Content-Type,这样编程时才能预料服务器返回的内容;

Referer: http://www.baidu.com/

当前请求来源页面的地址,某些场景下服务端会校检该字段来作统计分析、日志记录以及缓存优化等。

支付场景(微信当前调起H5支付的referer为空)下校检了该字段防止非法跳转进入的支付。

Cookie: PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST

响应 Response

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://www.infzm.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: x-requested-with, content-type, origin, cache-control, pragma, authorization, accept, accept-encoding
Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE

Content-Type: application/json

响应头中也存在Content-Type,这样编程时才能预料服务器返回的内容

Content-Type: text/html; charset=UTF-8

keyvalue
data{ foo: 'bar', baz: 'qux' }
dataType指定响应返回的数据类型,默认识别 HTTP 中 MIME 类型
contentType请求内容的编码类型 默认为 application/x-www-form-urlencoded

编码类型

请求 Requst

contentType 指定了请求内容的编码格式,而 jQ 默认使用 application/x-www-form-urlencoded ,使得实体内容会经过 $.param() 序列化

    $.param({ foo: 'bar', baz: 'qux' }) // "foo=bar&baz=qux"

使得实体数据 encoded

    $.ajax({
        url     : "/api/user/register_by_phone",
        type    : "POST",
        data    : jQuery.param({
            phone      : $(el_arr[0]).val(),
            verify_code: $(el_arr[1]).val(),
            password   : md5($(el_arr[2]).val()),
        }),
        timeout : 50000,
        dataType: 'json',
        success : function (res) {
            if (res.code != 200) {
                resolve(res.msg)
            } else {
                resolve(text_success_register)
            }
        }
    })
响应 Response

dataType 指定服务器返回的实体数据类型,不指定时,就要确保返回的 Content-Type 与实体内容编码一致

Content-Type Content-Type: application/json

为 Typecho 文章页加入微信分享功能

发表评论
撰写评论