HTTP协议-pzyyll

HTTP协议


Web浏览器和Web服务器程序进行数据交换,发送请求和应答时,要遵循一定的协议(不然也无法解析数据),这个协议就是超文本传输协议(Hyper Text Transfer Protocol, HTTP).
HTTP协议使用TCP协议作为支持,为其提供可靠的数据传输服务。

  • Web浏览器和Web服务器


    Paste_Image.png

HTTP1.1特性


  1. 应用层协议: HTTP工作在应用层, 运输层使用TCP协议, 默认端口为80
  2. 基于C/S模式: 客户端通过浏览器(并非一定是浏览器)向服务器发出请求, 服务器向客户端返回对请求的应答。
  3. 双向传输: 客户端向服务器发送请求, 服务器向客户端回应信息, 客户端负责将回应信息解析呈现给用户。客户端也可以将诸如表单一类的信息发送给服务器。
  4. 支持多个主机名: HTTP1.1版本允许一个Web服务器处理几十个甚至几百个虚拟机的请求。
  5. 持久连接:允许客户机在一个TCP连接中发送多个相关文档的请求。 HTTP1.0以前的版本一个请求需要一个新的TCP连接。
  6. 部分资源选择: 允许客户机只要求文档的部分资源的请求, 这样可以减少服务器的负载, 节省了资源。
  7. 支持高速缓存的代理: Web浏览器将用户浏览过的网页内容缓存在本机高速缓存中; 亦可在客户机和服务器之间建立代理服务器, 将本网络中曾经访问过的网页缓存在本地代理服务器中,客户端优先从代理服务器中读取信息, 减少不必要的Internet访问流量。
  8. 内容协商: 通过内容协商特性完成客户机和服务器的信息交换, 确定传输的细节。
  9. 安全性好:使用鉴别方法提高安全性能。

HTTP的工作过程


  • 客户机与服务器交互过程
交互过程
  1. Web服务器监听本地80端口。等待请求。
  2. 建立连接。由TCP协议建立连接, 开启一条传输通道, 提供数据传输的保障。
  3. 客户端发出请求。连接建立后, 即可向服务器发出请求, 获取数据。请求封装在HTTP请求报文中。
  4. Web服务器应答请求。 收到请求后, Web服务器将应答和对应文件放入HTTP应答报文中, 发送给客户端。
  5. 重复3, 4
  6. 通信结束, 关闭连接。

HTTP无状态特性

服务器不去记录访问的客户端。

持久连接和非持久连接

HTTP1.1默认使用持久连接。

  • 持久连接
Paste_Image.png

可一次连接请求多个文件

  • 非持久连接
Paste_Image.png

每次连接只能请求一个文件

HTTP报文


报文有请求和应答两种。一般以文本形式发送。

请求报文

客户端使用,指明所需文档的名字和位置。

  • 报文结构

Paste_Image.png

GET报文
最常用的的报文,请求参数以?para=val&para2=val2的形式加在URL后面。实体是空的,GET方式一般用来请求数据。当然要用来提交数据也没有人可以阻止你就是了。。。

Paste_Image.png
  1. Host: 表示所要访问的主机。Host字段与方法字段结合,可以明确要访问的资源。如上图中一个完整的URL应当是:http://i0.wp.com/ooly.club/pzyyll/wp-content/uploads/2016/04/cropped-b_authentique1.jpg?resize-825%2c510
  2. Connection: 告诉服务器对客户端做出应答后,是否保持连接,上图中的Keep-Alive,表示保持连接。例如一个网页文件中可能有多个图片连接,保持连接可以不断开连接而继续下载图片文件,提高效率和响应速度。
  3. Accept: 表示客户端所接受的文档类型。常见的还有 image/gif, image/jpeg, application/vnd.ms-word等等。
  4. User-Agent: 表示客户端类型。可以用于让服务器根据客户端类型返回应答内容,防止出现客户端无法理解应答的现象。
  5. Referer: HTTP參照位址referer,或HTTP referer),是HTTP表頭的一個欄位,用來表示從哪兒連結到目前的網頁,採用的格式是URL。換句話說,藉著HTTP參照位址,目前的網頁可以檢查訪客從哪裡而來,這也常被用來對付偽造的跨網站請求。
  6. Accept-Encoding: 表示客户端能够理解的编码方式。
  7. Accept-Language: 表示客户端优先接受的语言类型, 服务器可以根据语言的不同返回不同版本的主页。

POST报文
另一个最常用的请求报文,一般用于提交数据,或请求参数比较敏感的,例如密码信息等。因为用POST方式提交的数据都会放在请求报文的实体中。
POST报文的首部行还常常会用到下面这个:

  • Content-type: (实体解析类型)
    详细表单内容类型
    较为常用的就是以下两种:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • 另外还有
    • application/json
    • text/xml
    • 等等
      用一个例子作为说明,比如我要传递一个下面的表单信息:

Name:Zhili Cai
Pwd:1234567
Email: pzyyll@gmail.com

1.application/x-www-form-urlencoded: 用这种方式的实体内容的键值对用“KEY=VAL&KEY2=VAL2&..."的方法表示。并且会对KEY和VAL中的某些字符进行URI Encoding转义,具体有哪些可以参照这个,对于空格的处理是转换为‘+’.

POST /post.php HTTP/1.1/r/n
...
Content_type: charset=utf-8; application/x-www-form-urlencoded/r/n
/r/n                          //记得首部行与实体之间空一行
Name=Zhili+Cai&Pwd=1234567&Email=+pzyyll%40gmail.com

2.multipart/form-data:这种方式的实体就稍微有点复杂了,除了要指明content_type外,还要设置一个分隔字符串boundary,详细见下面:

POST /post.php HTTP/1.1
...
Content_type: multipart/form-data; boundary=abcdefghijklmn
                                      //实体与首部行之间空一行
--abcdefghijklmn                      //分割符前还要再加--
Content-Disposition: form-data; name="Name"
                                      //内容与首部行之间空一行
Zhili Cai
--abcdefghijklmn
Content-Disposition:form-data; name="Pwd"

1234567
--abcdefghijklmn
Content-Disposition:form-data; name="Email"

 pzyyll@gmail.com
--abcdefghijklmn--            //结束--boundary--

另外boundary还可以嵌套,以下是摘自官方文档的

   Content-Type: multipart/form-data; boundary=AaB03x

   --AaB03x
   Content-Disposition: form-data; name="submit-name"

   Larry
   --AaB03x
   Content-Disposition: form-data; name="files"
   Content-Type: multipart/mixed; boundary=BbC04y

   --BbC04y
   Content-Disposition: file; filename="file1.txt"
   Content-Type: text/plain

   ... contents of file1.txt ...
   --BbC04y
   Content-Disposition: file; filename="file2.gif"
   Content-Type: image/gif
   Content-Transfer-Encoding: binary

   ...contents of file2.gif...
   --BbC04y--
   --AaB03x--

Content-Disposition 用来指示出内容的类型,例如还有attachment,表示附件。具体可以查看文档

3.application/json: 需要浏览器和服务器支持

POST /post.php HTTP/1.1
...
Content_type: charset=utf-8; application/json
 //记得首部行与实体之间空一行
{"Name":"Zhili Cai", "Pwd":"1234567", "Email":" pzyyll@gmail.com"}

其它的请求方法还有HEAD, PUT, DELETE等

  • HEAD:与GET类似,但是应答报文无实体内容,一般用于检测URI是否有效,能否被访问。
  • PUT:用于将一个文档上传到服务器上,文档内容存储在实体中, 服务器根据URI创建一个新文档,并将实体内容存入新文档中,如果文档在服务器上已经存在,则会覆盖旧文档。执行成功返回对应的应答报文,失败则报错。
  • DELETE:用来删除服务器上的文档。
    各种方式可以查看RFC2616的第9章
应答报文

结构与请求报文类似,但是第一行是状态行,不是请求行了。

应答报文

一个实例:

                        --> HTTP/1.1 302 Found
                            Server: nginx
                            Date: Wed, 04 May 2016 06:06:52 GMT
                            Content-Type: text/html; charset=UTF-8
                            Transfer-Encoding: chunked
                            Connection: keep-alive
                            X-Powered-By: PHP/5.4.41
                            Expires: Wed, 11 Jan 1984 05:00:00 GMT
                            Cache-Control: no-cache, must-revalidate, max-age=0
                            Pragma: no-cache
                            Set-Cookie: [52 bytes were stripped]
                            X-Frame-Options: SAMEORIGIN
                            Set-Cookie: [257 bytes were stripped]
                            Set-Cookie: [247 bytes were stripped]
                            Set-Cookie: [249 bytes were stripped]
                            Location: http://ooly.club/pzyyll/wp-admin/

另外再补充下,现在的HTTP协议已经到版本2了,请求行和状态行,首部行和现在的不太一样
感兴趣的可以查看文档RFC7540

     GET /resource HTTP/1.1           HEADERS
     Host: example.org          ==>     + END_STREAM
     Accept: image/jpeg                 + END_HEADERS
                                          :method = GET
                                          :scheme = https
                                          :path = /resource
                                          host = example.org
                                          accept = image/jpeg
/******************************************************/
     POST /resource HTTP/1.1          HEADERS
     Host: example.org          ==>     - END_STREAM
     Content-Type: image/jpeg           - END_HEADERS
     Content-Length: 123                  :method = POST
                                          :path = /resource
     {binary data}                        :scheme = https

                                      CONTINUATION
                                        + END_HEADERS
                                          content-type = image/jpeg
                                          host = example.org
                                          content-length = 123

                                      DATA
                                        + END_STREAM
                                      {binary data}
/******************************************************/
     HTTP/1.1 100 Continue            HEADERS
     Extension-Field: bar       ==>     - END_STREAM
                                        + END_HEADERS
                                          :status = 100
                                          extension-field = bar

     HTTP/1.1 200 OK                  HEADERS
     Content-Type: image/jpeg   ==>     - END_STREAM
     Transfer-Encoding: chunked         + END_HEADERS
     Trailer: Foo                         :status = 200
                                          content-length = 123
     123                                  content-type = image/jpeg
     {binary data}                        trailer = Foo
     0
     Foo: bar                         DATA
                                        - END_STREAM
                                      {binary data}

                                      HEADERS
                                        + END_STREAM
                                        + END_HEADERS
                                          foo = bar

首部行中还有一个Cookie来记录用户行为,现在也用的比较广。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容