Http协议位于网络五层结构的最上层应用层。它建立在TCP协议之上,是个无状态的协议,典型的应用是网络浏览器以及移动端数据传输。本文将介绍Http请求的格式,并对请求数据的各部分做一个详细介绍。
Http协议包括多个方法:Get,Post,Put,Delete,Head,Patch,Options等。我们重点关注最常用的Get和Post请求。
一次请求包括两个过程,Request过程和Response过程,Request过程发出数据请求,携带请求的各项参数,Response过程返回请求的数据。
Http Request
Http Request包括三部分:请求行,请求头和请求体。
第一行是请求行,格式是:方法+路径+Http版本,以空格分隔。从第二行开始是请求头,由若干个键值对构成,每个键值对一行。请求头结束后空一行,接着是请求体。
POST请求的参数放在请求体里,GET请求没有请求体,请求的参数以键值对的形式存放在path里面。请求头里的键值对包括预定义键值对和自定义键值对,键值对内容包括请求的Host,User-agent,编码方式,请求体的类型,请求体的长度,分隔符等等信息,大部分都是可选的,我们也可以随意添加自定义的键值对来满足某些需求。下面是一个Post请求的实例:
Http Response
Http Response也包括三部分:响应状态行,响应头和响应体。
第一行是响应状态行包括Http版本+响应状态,以空格分隔。从第二行开始是响应头,包含若干个键值对,每个键值对占一行。后面空一行,接着是响应体。
请求体可以包括多个part,通过header里面的分隔符分隔,比如音频上传时利用请求体里两个part分布存储文件类型和音频数据。
User-agent键值对
Http Request Header里有个user-agent字段,是用来存放发起请求的客户端或者浏览器的标识信息的,比如浏览器的名称版本,操作系统的名称版本,客户端的名称版本等。
浏览器的user-agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
webview原始user-agent:
Mozilla/5.0 (Linux; U; Android 4.2.1; zh-cn; MI 3 Build/JOP40D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
我们自己在后面追加
Chunyuyisheng/7.3.0 (iPhone; iOS 8.4; Scale/2.00) ,注意第一个有空格,方便隔开原始字符串,以便服务器正则判断
最后生成类似 下面的字符串:
Mozilla/5.0 (Linux;
U; Android 4.2.1; zh-cn; MI 3 Build/JOP40D) AppleWebKit/534.30 (KHTML, like
Gecko) Version/4.0 Mobile Safari/534.30 Chunyuyisheng/7.3.0 (iPhone; iOS 8.4;
Scale/2.00)
user-agent就是一个存放发起请求的端一些附加信息的地方,至于具体写入啥是由客户端和服务器协商决定的,没有硬性标准。
Cookie键值对
Cookie键值对存储的是一些标志用户身份或设置的信息,如session ID,language等。用户通过浏览器首次访问某个网站的时候,服务器生成一个cookie,并把它放在http响应的header里面,下次再次访问该网站的时候,浏览器会在http请求的header里面带上这个cookie值,服务器可以建立一个cookie值到用户表的映射,然后就可以利用这个识别用户。
最基本的Cookie:
==Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42
==User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
指定Cookie的Path和Domain属性
==Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com
==User Agent -> Server ==
Cookie: SID=31d4d96e407aad42
包含多个Cookie,一个名字是SID,另一个名字lang,名为SID的Cookie指定了Path,Secure和HttpOnly属性;名为lang的Cookie指定了Path和Domain属性:
==Server -> User Agent ==
Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com
==User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US
指定名为lang的Cookie的过期时间:
==Server -> User Agent ==
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
==User Agent -> Server ==
Cookie: SID=31d4d96e407aad42; lang=en-US
服务器通过给名为lang的Cookie指定一个过去的时间来删除该Cookie:
==Server -> User Agent ==
Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT
== User Agent -> Server ==【客户端发给服务器的Cookie不再包含lang】
Cookie: SID=31d4d96e407aad42
Third-Party Cookies
如果用户访问某个网页,该网页嵌入了三方广告,打开网页的时候会向广告服务区发送请求,广告服务器返回的Response里会返回一个Cookie,下次用户打开其他网页的时候,如果该网页嵌入了同一个第三方广告平台,那请求广告内容的Request里会自动把之前返回的Cookie添加进去,从而能让广告服务器识别出该用户,根据之前浏览的内容给用户推荐相应的广告。这就是为什么能给用户展示之前访问内容相关的广告。