HTTP全解析

一.Http是什么?

中文名称--超文本传输协议,是TCP/IP协议族的最顶层-应用层html

二.Http请求格式

URL格式分为三部分:
协议类型://服务器地址(和端口号)/路径(Path)
https://segmentfault.com/writ...node

三.Http的报文格式

1.请求:

clipboard.png

  • 请求报文---->分为 : 请求行,Header,Body三部分。
  • 请求行中包括请求的方式(GET,POST等),请求的路径(主机地址以后的部分),Http的版本号
  • 请求头包括一些上传信息的属性,是固定名称的键值对形式,最后一个请求头以后是一个空行,这个行很是重要,它表示请求头已经结束,接下来的是请求正文。
  • 请求体是上传的内容,通常配合请求头Content-Type为 x-www-form-urlencoded的形式使用(表单格式),GET请求没有请求体。

2.响应:

clipboard.png

  • 响应报文---->分为:响应行,Header,Body三部分。
  • 响应行中包括Http版本号,响应状态码和响应状态信息三部分。
  • 响应体根据服务器返回的数据格式为主,通常响应体都是返回JSON格式。

四.请求方法:列举常见的5种

理论上讲 GET POST 除了这两个词不同以外没有任何区别。区别都是客户端的约定俗成,如下均是在HTTP以标准规范使用的状况下为基础。

GET

  • 用于直接从服务器上获取资源。
  • 对服务器数据不进行修改,知足幂等性(反复调用屡次时会获得相同的结果。例如执行十次相同的GET请求至关于从服务器获取十次数据,但并不会对服务器数据形成修改)。

不发送Body请求体。nginx

GET  /users/1  HTTP/1.1 

Host: api.github.com

POST

  • 用于增长或修改服务器上的资源。
  • 发送给服务器的内容写在Body中。
  • 不知足幂等性(增长资源的时候执行一次和执行十次不一样,执行一次增长一个,执行十次增长十个)。
POST /users HTTP/1.1    
                                               
Host: api.github.com 
Content-Type: application/x-www-form-urlencoded  (Content-Type为 “application/x-www-form-urlencoded”时,才会读取Body中的内容)
Content-Length: 13 

name=lvzishen&gender=male

PUT

  • 用于修改服务器上的资源(和POST请求功能有些重复了,POST既能新增又能修改资源,PUT只能修改资源)。
  • 发送给服务器的内容写在Body中。
  • 知足幂等性。
PUT /users HTTP/1.1            
                                       
Host: api.github.com 
Content-Type: application/x-www-form-urlencoded  (Content-Type为 “application/x-www-form-urlencoded”时,才会读取Body中的内容)
Content-Length: 13 

name=lvzishen&gender=male

DELETE

  • 用于删除服务器上的资源。
  • 不发送BODY。
DELETE /users/1 HTTP/1.1 

Host: api.github.com

HEAD

  • 和GET请求同样都是从获取资源(和GET请求不一样的是响应数据中没有BODY)。
  • 通常能够用于下载文件,好比先用HEAD请求去看是否支持服务器是否支持分段下载功能,若是支持再用GET或POST请求配置相应分段传输的数据去下载获取资源,避免无用的资源浪费。检查资源的有效性(如先用HEAD拉去获取ACCEPT RANGE总长度,再用GET请求配合RANGE去下载部份内容)。
HEAD  /users/1  HTTP/1.1 

Host: api.github.com

五.Status Code状态码

用于对相应结果做出类型化描述。git

  • 1xx:临时性消息。如:100 (继续发送)、101(正在切换协议)
  • 2xx:成功。最典型的是 200(OK)、201(建立成功)。 
  • 3xx:重定向。如 301(永久移动)、302(暂时移动)、304(内容未改变)。 301表示搜索引擎在抓取新内容的同时也将旧的网址交换为重定向以后的网址;302表示旧地址A的资源还在(仍然能够访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址(浏览器缓存的地址)。
  • 4xx:客户端错误。如 400(客户端请求错误)、401(认证失败)、403(被禁止)、404(找不到内容)。  401配合Authorization,403好比IP被禁止,404好比传的URL错误
  • 5xx:服务器错误。如 500(服务器内部错误)。

六.Header

1.Header是什么?
HTTP消息的metadata(元数据)。 github

2.什么是元数据?
通俗的讲就是数据的属性。以一个登陆接口为例,用户名密码是上传的数据(放在BODY中),那么用户名密码的长度( Content-Length)、以什么类型( Content-Type )上传等等就是它的元数据。web

几个重要的Header

1.Host

目标主机。注意:不是在网络上用于寻址(寻址用DNS)的,而是在目标服务器(找到IP后一个IP下有可能有多个主机名,肯定访问的是哪个主机)上用于定位子服务器的。算法

2.Content-Type

指定Body的类型。主要分为四类:

(1). text/html: 请求 Web 页面是返回响应的类型,Body 中返回 html文本。格式以下:json

HTTP/1.1 200 OK 

Content-Type: text/html;charset=utf-8 
Content-Length: 853 ......

<!DOCTYPE html>
<html>
<head>
     <meta charset="utf-8">
.....

(2). x-www-form-urlencoded : 纯文本表单的提交方式(只有以表单形式提交时,才会读取Body中的内容)。 格式以下:segmentfault

POST /users HTTP/1.1

Host: api.github.com 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 27 

name=lvzishen&gender=male

对应 Retrofit 的代码:api

@FormUrlEncoded      <--表明的是以普通表单(application/x-www-form-urlencoded)上传文本参数,加了这个注解后才会读取@Field中的参数,由于@Field最后会转变为请求体Body中的内容.
@POST("/users") 
Call addUser(@Field("name") String name, @Field("gender") String gender);

(3).multipart/form-data :页面含有二进制文件时的提交方式(上传文件或文字均可以,可是通常没有用此上传纯文字,由于会多加如boundary、分隔符等字符,浪费流量和带宽)。(只有以表单形式提交时,才会读取Body中的内容)。 格式以下:

POST /users HTTP/1.1 
Host: hencoder.com 
Content-Type: multipart/form-data; boundary=----        boundary为起始点
WebKitFormBoundary7MA4YWxkTrZu0gW 
Content-Length: 2382 

------WebKitFormBoundary7MA4YWxkTrZu0gW                 WebKitFormBoundary7MA4YWxkTrZu0gW<--为分隔符
Content-Disposition: form-data; name="name" 

rengwuxian 
------WebKitFormBoundary7MA4YWxkTrZu0gW 
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg" 
Content-Type: image/jpeg 

JFIFHHvOwX9jximQrWa......

(4). application/json , image/jpeg , application/zip ...

单项内容(文本或非文本均可以),用于 Web Api 的响应或者 POST / PUT 的请求
请求中提交 JSON:

POST /users HTTP/1.1

Host: hencoder.com 
Content-Type: application/json; charset=utf-8 
Content-Length: 38 

{"name":"lvzishen","gender":"male"}

响应中返回JSON:

HTTP/1.1 200 OK

content-type: application/json; charset=utf-8 
content-length: 234

[{"login":"mojombo","id":1,"node_id":"MDQ6VXNl cjE=","avatar_url":"https://avatars0.githubuse rcontent.com/u/1?v=4","gravat......

image/jpeg:提交或获取图片

POST /user/1/avatar HTTP/1.1 

Host: hencoder.com 
Content-Type: image/jpeg 
Content-Length: 1575 

JFIFHH9......

3.Content-Length

指定 Body 的长度(字节)。用于二进制文件中的长度读取,由于不能肯定读取到哪里,因此规定长度,读取到对应长度后表明读取完成再也不读取。

4.Transfer: chunked (分块传输编码 Chunked Transfer Encoding)

用于当响应发起时,内容长度还没能肯定的状况下。和 Content-Length 不一样时使用。用途是尽早给出响应,减小用户等待。

HTTP/1.1 200 OK 

Content-Type: text/html 
Transfer-Encoding: chunked

4 
Chun                  <--不断给出数据 先给4字节的Chun,再给9字节的ked Trans,.....,0表明传输完成所有加载完毕。
9 
ked Trans 
12 
fer Encoding 
0

5.Location

指定重定向的目标的URL

6.User-Agent

用户代理,便是谁实际发送请求、接受响应的,例如手机浏览器、某款手机 App。

7.Range / Accept-Range

按范围取数据

  • Accept-Range: bytes 响应报文中出现,表示服务器支持按字节来取范围数据
  • Range: bytes =<start>-<end> 请求报文中出现,表示要取哪段数据
  • Content-Range:<start>-<end>/total 响应报文中出现,表示发送的是哪段数据

做用:断点续传、多线程下载。

8.Cache

做用:在客户端或中间网络节点缓存数据,下降从服务器取数据的频率,以提升网络性能。

9.Cookie

clipboard.png
clipboard.png

  1. 服务器须要客户端保存的内容,放在 Set-Cookie headers 里返回,客户端会自动保存。
  2. 客户端保存的 Cookies,会在以后的全部请求中都携带进 Cookie header 里发回给服务 器。
  3. 客户端保存 Cookie 是按照服务器域名来分类的,例如 shop.com 发回的 Cookie 保存下来 之后,在以后向 games.com 的请求中并不会携带。
  4. 客户端保存的 Cookie 在超时后会被删除、没有设置超时时间的 Cookie (称做 Session Cookie)在浏览器关闭后就会自动删除;另外,服务器也能够主动删除还未过时的客户端 Cookies。

10.Authorization

(1)Basic

格式:Authorization: Basic username:password(Base64ed) 对用户名密码作Base64编码,不是加密的,Base64只是编码。

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

(2)Bearer

格式:Authorization: Bearer token
bearer token 的获取方式:
经过 OAuth2 的受权流程 OAuth2 的流程
图片描述

clipboard.png

  1. 第三方网站向受权受权方网站申请第三方受权合做,拿到 client id 和 client secret
  2. 用户在使用第三方网站时,点击「经过 XX (如 GitHub) 受权」按钮,第三方网站将跳转到受权网站,并传入 client id 做为本身的身份标识
  3. 受权方网站根据 client id ,将第三方网站的信息和第三方网站须要的用户权限展现给用户,并询问用户是否赞成受权
  4. 用户点击「赞成受权」按钮后,受权方网站将跳转回第三方网站,并传入 Authorization code 做为用户承认的凭证。
  5. 第三方网站将 Authorization code 发送回本身的服务器
  6. 服务器将 Authorization code 和本身的 client secret 一并发送给受权方的服务器,受权方 服务器在验证经过后,返回 access token。OAuth 流程结束。
  7. 在上面的过程结束以后,第三方网站的服务器(或者有时客户端也会)就可使用 access token 做为用户受权的令牌,向受权方网站发送请求来获取用户信息或操做用户帐户。但这已经在 OAuth 流程以外。

为何 OAuth 要引入Authorization code,并须要申请受权的第三方将 Authorization code 发送回本身的服务器,再从服务器来获取 access token,而不是直接返回 access token ?这样复杂的流程意义何在?

答:为了安全。OAuth 不强制受权流程必须使用 HTTPS,所以须要保证当通讯路径中存在窃听者时,依然具备足够的安全性。


在自家 App 中使用 Bearer token
有的 App 会在 Api 的设计中,将登陆和受权设计成相似 OAuth2 的过程,但简化掉 Authorization code 概念。即:登陆接收请求成功时,会返回 access token,而后客户端在之 后的请求中,就可使用这个 access token 来当作 bearer token 进行用户操做了。 (这么作失去了使用OAuth2的意义)

Refresh token 用法:access token 有失效时间,在它失效后,调用 refresh token 接口,传入efresh_token 来获取新的 access token。

{
"token_type": "Bearer", 
"access_token": "xxxxx", 
"refresh_token": "xxxxx", 
"expires_time": "xxxxx" 
}

目的:安全。
当 access token 失窃时,因为它有失效时间,所以坏人只有较短的时间来「作坏事」;同时,因为(在标准的 OAuth2 流程中)refresh token 永远只存在与第三方服务的服务 器中,所以 refresh token 几乎没有失窃的风险。

七.RESTful是什么?

以HTTP标准协议去使用HTTP。
好比:

  1. 规范地使用method 来定义网络请求操做(删除数据用DELETE请求,而不是用POST。获取数据不要使用POST请求而应该使用GET请求)。
  2. 规范地使用 status code 来表示响应状态。

八.HTTP1.0 HTTP 1.1主要区别

一.长链接 Keep-Alive

HTTP 1.0须要使用keep-alive参数来告知服务器端要创建一个长链接,而HTTP1.1默认支持长链接。Connection:keep-alive(虽然是不断开可是每次也只能串行的执行HTTP请求,2.0才支持并行
HTTP是基于TCP/IP协议的,建立一个TCP链接是须要通过三次握手的,有必定的开销,若是每次通信都要从新创建链接的话,对性能有影响。所以最好能维持一个长链接,能够用个长链接来发多个请求。
持久链接的时间参数,一般由服务器设定,好比 nginx 的 keepalivetimeout,keepalive timout 时间值意味着:一个 http 产生的 tcp 链接在传送完最后一个响应后,还须要 hold 住 keepalive_timeout (一般为5-15S)秒后,才开始关闭这个链接;

二.节约带宽

HTTP 1.1支持只发送header信息(不带任何body信息),若是服务器认为客户端有权限请求服务器,则返回100,不然返回401。客户端若是接受到100,才开始把请求body发送到服务器。
这样当服务器返回401的时候,客户端就能够不用发送请求body了,节约了带宽。
另外HTTP还支持传送内容的一部分。这样当客户端已经有一部分的资源后,只须要跟服务器请求另外的部分资源便可。这是支持文件断点续传的基础。

三.HOST域

如今能够web server例如tomat,设置虚拟站点是很是常见的,也便是说,web server上的多个虚拟站点能够共享同一个ip和端口。
HTTP1.0是没有host域的,HTTP1.1才支持这个参数。

九.HTTP1.1 HTTP 2.0主要区别

一.多路复用的单一长连接

1.单一长链接
在HTTP/2中,客户端向某个域名的服务器请求页面的过程当中,只会建立一条TCP链接,即便这页面可能包含上百个资源。 单一的链接应该是HTTP2的主要优点,单一的链接能减小TCP握手带来的时延 。HTTP2中用一条单一的长链接,避免了建立多个TCP链接带来的网络开销,提升了吞吐量。
2.多路复用
HTTP2虽然只有一条TCP链接,可是在逻辑上分红了不少stream。
HTTP2把要传输的信息分割成一个个二进制帧,首部信息会被封装到HEADER Frame,相应的request body就放到DATA Frame,一个帧你能够当作路上的一辆车,只要给这些车编号,让1号车都走1号门出,2号车都走2号门出,就把不一样的http请求或者响应区分开来了。可是,这里要求同一个请求或者响应的帧必须是有有序的,要保证FIFO的,可是不一样的请求或者响应帧能够互相穿插。这就是HTTP2的多路复用,是否是充分利用了网络带宽,是否是提升了并发度?

clipboard.png

二.Header数据压缩

HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
至关于创建一个映射表,如GET方法直接定义为映射表中的数字2,那么GET请求时请求方法写2就能够而不用写GET,这样就能够节省流量和空间。

三.服务器推送

这个功能一般被称做“缓存推送”。主要的思想是:当一个客户端请求资源X,而服务器知道它极可能也须要资源Z的状况下,服务器能够在客户端发送请求前,主动将资源Z推送给客户端,这样当使用Z资源时就不用请求网络直接本地取数据就能够了,加快获取速度。

相关文章
相关标签/搜索