HTTP

HTTP协议

协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的客户端,目前我们使用的是HTTP/1.1版本

当我们打开客户端,在地址内输入URL,然后我们就看到了网页,原理是怎样的呢?

实际上我们输入URL后,我们的客户端给web服务其发送了一个Request,web服务其接收到Request后进行处理,生成相应的Response,然后发送给客户端,客户端解析Response中的HTML,这样我们就看到了网页

我们的Request有可能是经过了代理服务器,最后才到达了web服务器

URL

url地址用于描述一个网络上的资源,基本格式如下:

schema://host[:port#]/path/.../[;params][?query][#anchor]

  • schema 指定底层使用的协议(例如:http、https、ftp)
  • host HTTP服务器的IP地址或者域名
  • port# HTTP服务器端口号,默认的是80,这种情况下端口号可以省略,如果使用了其它端口号,必须指明
  • path 访问资源的路径
  • url-params 服务器文件夹路径
  • query 发送给http服务器的数据
  • anchor 锚点

特别注意一个点,HTTP协议是无状态的,同一个客户端的本次请求和上次请求是没有对应关系的,对http服务器来说,它并不知道两个请求来自同一个客户端,为了解决这个问题,web程序引入了cookie机制

无状态代表每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况

Cookie 是怎样产生的, 如我们第一次通过客户端访问一个web服务,在服务端会产生一个会话信息 Session, 该服务器响应你的请求时会将该会话信息的 session_id 以 cookie 写入到你的客户端,下次访问时,会带着这个cookie信息进行会话验证;
而 APP 的接口是没有通过客户端访问的,所以也就在服务器端不会生成session,在客户端也不会写入cookie,那么也就拿不到会话信息,所以,为了能够像客户端那样记住同一客户的信息,Token就诞生了, 用户每次访问服务端时,会带着这个Token,而服务端通过这个Token拿到用户的相关信息,然后再处理。

HTTP消息的结构

Request消息的结构,Request消息分为三部分,第一部分叫请求行(General),求而部分叫HTTP header,第三部分是body


http.png
General

Request URL:http://www.cnblogs.com/mvc/blog/GetComments.aspx?postId=4783633&blogApp=chaoran&pageIndex=0&anchorCommentId=0&_=1516261661347

请求的页面地址

Request Method:GET

请求的方法

Status Code:200 OK

服务器返回的状态码

Remote Address:101.37.225.65:80

远程地址

Referrer Policy:no-referrer-when-downgrade

用于过滤Referrer(上一级链接跳转路径),比如从一个网站跳转时可能将原来网站的token直接作为报头传递,该方法就是为了规避这个问题而提出的,默认值no-referrer-when-downgrade表示当降级发生(https=》htttp)时,不传递Referrer报头,还有其他可选值,但是目前对该规范支持的不多,就不详细说了,有兴趣可以查阅其他文档

Request header

Pragma:no-cache

Pragma的作用是防止页面被缓存,在HTTP/1.1版本中,他和Cache-Control的作用一模一样,Pragme只有这一个用法

Cache-Control:no-cache

Cache-Control作用是来指定缓存机制,用法很多,我们查看其中三个,如果有兴趣,可以参考其他资料了解

  • Cache-Control:Public 可以被任何缓存所缓存
  • Canche-Control:private 所有内容只会缓存到私有缓存中
  • Cache-Control:no-cache 必须与服务器确认返回的响应是否被更改,然后才能使用该响应来继续对同一个网址的请求,在存在Etag的情况下,会先判断Etag然后再确认是否请求新的资源或读取本地资源
  • Cache-Control:no-store 所有内容都不会被缓存到缓存或 Internet 临时文件中
  • Cache-control:max-age=500 缓存的内容将在500秒后失效,在这段时间内客户端不会向服务端做缓存校验

Accept:text/html

Accept作用是声明客户端可以接收的媒体类型,上面的这一段表示可以接受服务器返回text/html类型的文档,也就是我们常说的html文档,如果服务器无法返回该类型的文档,那么服务器应该返回一个406错误(表示不可接受)

通配符*表示客户端可以处理所有类型,emmm,一般情况下都是给服务器发这个

Accept-Language:zh-CN,zh;q=0.9

Accept-Language的作用是客户端声明自己可以接受的语言类型

Accept-Encoding:gzip, deflate

Accept-Charset的作用是客户端声明自己接受的字符编码

Cookie:_ga=GA1.2.611741651.151617515

Accept-Encoding的作用是客户端声明自己接受的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法,上面的就是声明可以接受gzip,deflate的压缩方法

User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1

Use-Agent作用是告诉服务器客户端使用的操作系统和客户端的名称和版本

Accept-Charset:utf-8

Cookie作用是将cookie的值发送给服务器

Content-Type: application/x-www-form-urlencoded

Content-type作用是表示请求的类型

  • 一般的URL类型参数 application/x-www-from-yrlencoded
  • 包体是json时类型 application/json
  • 提交表单时 mulitpart/form-data

Content-Length: 38

Content-Length作用是表示表示请求体的长度

Referer:http://www.cnblogs.com/chaoran/p/4783633.html

Referer表示当前请求的上一个请求地址,通过这个参数我们可以统计有外联链接跳转到我们页面的数量

Connection:keep-alive

Connection:keep-alive当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP链接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的链接,但是keep-alive不会永久保持链接,它有一个保持时间,在超过设定时间后会断开本次的TCP链接再次建立TCP链接,如果想要关闭链接使用Connection:close

Host:www.cnblogs.com

Host请求报头域主要用于指定被请求资源的Internet主机和端口号,如果端口号是80则会被默认忽略

If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT

if-Modified-Since表示服务器上一次返回的内容被服务器修改的时间,如果服务器没有返回,本次请求就不会带这个头,也就是说这个必须是在服务器支持的情况下才会返回,在服务器支持的情况下,在返回一个html的时候,会设置一个相应的头:Last-Modified来表示服务器记录的最后一次修改内容的时间,客户端在接收到响应后会保存这个头,在下一次请求该接口时用If-Modified-Since上一次保存的接收到的服务器返回的响应头中的last-Modified的值再带回服务器,当然换药结合服务器上次返回的Cache-Control头来做判断

If-None-Match:fca75d26f6dc8111a7d1b24e9debd652

If-None-Match表示上次请求这个接口时服务器缓存的Etag,如果上次没有返回Etag则不带这个头

缓存机制

如果服务器希望客户端缓存某次请求时,会返回Last-ModifiedEtag两个头,客户端第二次会用If-Modifed-SinceIf-None-Match请求时会带上这两个头,服务器会做判断,如果If-Modified-Since的时间和文档的修改时间一致或者更小并且Etag一致,服务器会判断服务器的文档没有被修改富哦,服务器会返回304状态码,告诉客户端上次请求缓存起来的文档还是有效的,可以直接使用上一次请求的文档,比如我们一个文档有500M大小,那么只需要几秒钟来做一下验证缓存,而不需要花好多时间来通过流来传输文件

Response header

Date:Thu, 18 Jan 2018 02:58:12 GMT

Date是表示服务器响应的时间,返回格式是格林尼治时间

Server:ZWS

Server表示服务器软件名称

Location:www.youlanw/agent/index.html

Location表示服务器地址已经变更,一般是在响应码在300-400之间才会有,304表示缓存重定向,不会返回这个头,这个头的值就是新的url,也可能是相对路径

//客户端请求
www.youlanw.com
//服务端返回
/agent/index.html
//客户端重定向地址
www.youlanw.com/agent/index.html

Content-Encoding:gzip

Content-Encoding表示服务端返回内容的压缩算法,对应客户端请求的Accept-encoding

Set-Cookie:name=value; expires=Tue, 25-Apr-17 04:57:47 GMT; domain=域名; path=/

其中name是cookie的名字,value是cookie的值,expires表示cookie的过期时间,domain表示作用于的域名,path表示在这个域名下生效的路径,但是注意,在客户端发送cookie是提交的只有name和value

Etag:"bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f"

Etag是HTTP1.1中才加入的一个属性,用来帮助服务器控制web端的缓存验证,它的原理是这样的,当客户端请求服务器的某项资源(A)时,服务器根据A的当前内容算出一个hash值(3f80f-1b6-3e1cb03b),并通过Etag返回给客户端,客户端会把3f80f-1b6-3e1cb03b和A同时缓存在本地,当下次再次向服务器请求A资源时,会通过雷士IF-None-Match:3f80f-1b6-3e1cb03b的请求头把Etag发送给服务器,服务器再次计算A的哈希值,并和客户端返回的值作比较,如果没有变化就给客户端返回一个304未修改,这样通过控制客户端缓存,可以节省服务器的带宽,因为服务器不需要每一次都把全量数据返回客户端

我们需要注意的是Etag在HTTP中并没有指定固定的格式,hash是比较理想的选择,可以作为类似于资源指纹没如果资源发生变化就申城一个新的指纹,这样就可以快速的比较资源的变化,在服务端的实现中,很多情况下并不会用hash来计算Etag,这回严重浪费服务器资源,很多网站默认是禁用Etag的,或者通过判断修改时间来生成Etag,但这样的做法其实和另外一个控制属性Last-Modified就雷同了,而且面对不断变化的资源斌不是很有效,只适合不太敏感的静态资源

HTTP消息状态码

你可能感兴趣的:(HTTP)