HTTP

关于HTTP这个造作的协议

1 what is HTTP?

HTTP 协议是 Hyper Text Transfer Protocol (超文本传输协议)的缩写
我记得我们老班说过一个故事,从前 有座山有个大水逼,他的毕业设计全是那啥那啥抄的, 然后答辩的老师也是心知肚明,就问随便他 http 是什么(毕设做的 web ), 然后就炸了《HTTP》

2 HTTP 的 特点

HTTP协议永远都是客户端发起请求,服务器回送响应。

单向

HTTP协议永远都是客户端发起请求,服务器回送响应。这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。

无状态

协议的状态是指下一次传输可以“记住”这次传输信息的能力。 http是不会为了下一次连接而维护这次连接所传输的信息,为了保证服务器内存。 从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。

Connection: keep-alive

那么Connection: keep-alive又是怎么一回事, HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接。 从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接,这样可以节省资源。 Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

3 what is URL?

HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。 URL 是一种特殊类型的 URI ,包含了用于查找某个资源的足够的信息

说白了就是资源的家庭住址

4 HTTP 到底长啥样

HTTP是一个位于传输层上的应用层的协议

《HTTP》
HTTP Request 报文解析

一个 http Request 报文结构大概就是这个逼样,当然http response也差不多是这个逼样

《HTTP》

一个常见的 GET 请求如的下(wireshark), 从报文上来看 GET 和 POST 在报文格式上是没有任何区别的, 只是 GET 请求数据部分(也叫主体)是空的而已, 以后出去面试官问你你就可以这么说,唬住面试官你就可以要50k

 

了解了 HTTP 报文现在就可以自己用 socket 实现一个 超简洁的 http 服务器了

 

昨天看到来了篇文章说不对,GET 和 POST 是有区别的 传送门 文章中说

GET产生一个TCP数据包;POST产生两个TCP数据包。
那么辟谣来了,发送数据包的数量会和你的上传的数据大小有关系,而且和浏览器的版本有关系,有些版本的浏览器是有这个行为的(据说的某低版本的垃圾浏览器会先传head再传body)

那么我们就已chrome最新版本为例(版本 59.0.3071.115(正式版本) (64 位) FOR Linux)

稍微有点常识的同学会知道,tcp数据包是有大小限制的,GET 由于数据大小有限制(url长度是有限制的)所以基本上不会超过1个数据包(我可没说死啊,万一将来被打脸), 但是对于数据小的POST请求来说只会发送一个数据包,对于数据大的(比如上传图片)POST 请求,会发送很多的数据包。 有wireshark的图为证

《HTTP》

课件小请求一个包就解决了

《HTTP》

超级大请求,仔细看上面有一行叫10008 Reassembles TCP segments 也就是说这个请求是分了1w个TCP segments上传的(这是一个10M的图,没上万数据包是传不上去的)
HTTP Response 报文

上面的socket小服务器的response报文是,与request类似就不叙述了

 

 

HTTP状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:

  • 1xx:指示信息–表示请求已接收,继续处理
  • 2xx:成功–表示请求已被成功接收、理解、接受
  • 3xx:重定向–要完成请求必须进行更进一步的操作
  • 4xx:客户端错误–请求有语法错误或请求无法实现
  • 5xx:服务器端错误–服务器未能实现合法的请求

常见的状态码

  • 200: OK 客户端请求成功
  • 301: Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
  • 400: Bad Request 客户端请求的语法错误,服务器无法理解
  • 401: Unauthorized 请求要求用户的身份认证
  • 403: Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
  • 404: Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面
  • 500: Internal Server Error 服务器内部错误,无法完成请求(通俗的讲就是服务器炸了)
  • 503: Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中

HTTP请求方法

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

  • GET 请求指定的页面信息,并返回实体主体。
  • HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
  • POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
  • PUT 从客户端向服务器传送的数据取代指定的文档的内容。
  • DELETE 请求服务器删除指定的页面。
  • CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
  • OPTIONS 允许客户端查看服务器的性能。
  • TRACE 回显服务器收到的请求,主要用于测试或诊断。

HTTP头字段(HTTP header fields)

HTTP常见的请求头

  • If-Modified-Since:把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。
  • If-None-Match:If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag.使用这样的机制将提高网站的性能。例如: If-None-Match: “03f2b33c0bfcc1:0″。
  • Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝;在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一样。Pargma只有一个用法, 例如: Pragma:no-cache 注意: 在HTTP/1.0版本中,只实现了Pragema:no-cache, 没有实现Cache-Control
  • Cache-Control:指定请求和响应遵循的缓存机制。缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程)。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage。
    Cache-Control:Public 可以被任何缓存所缓存
    Cache-Control:Private 内容只缓存到私有缓存中
    Cache-Control:no-cache 所有内容都不会被缓存
    Cache-Control:no-store 用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
    Cache-Control:max-age 指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
    Cache-Control:min-fresh 指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
    Cache-Control:max-stale 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
  • Accept:浏览器端可以接受的MIME类型。Accept:浏览器端可以接受的MIME类型。例如:Accept: text/html 代表浏览器可以接受服务器回发的类型为 text/html 也就是我们常说的html文档,如果服务器无法返回text/html类型的数据,服务器应该返回一个406错误(non acceptable)。 可以返回多个类型用,隔开,例如 Accept: application/json, text/plain, */*通配符 代表任意类型, 例如 Accept: /* 代表浏览器可以处理所有类型,(一般浏览器发给服务器都有发这个)。
  • Accept-Encoding:浏览器申明自己可接收的编码,通常指定压缩方法 例如Accept-Encoding: gzip, deflate\r\n
  • Accept-Language:浏览器申明自己接收的语言。例如 Accept-Language: zh-CN,zh;q=0.8
  • Accept-Charset:浏览器可接受的字符集。如果在请求消息中没有设置这个域,缺省表示任何字符集都可以接受。
  • User-Agent:浏览器的身份标识字符串,好像可以随便乱改,
  • Content-Type: 请求体的MIME类型
  • Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
  • Connection: 客户端(浏览器)想要优先使用的连接类型 例如:Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。HTTP 1.1默认进行持久连接。利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,
  • Host:(发送请求时,该头域是必需的)主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。
  • Cookie:将cookie的值发送给HTTP服务器。
  • Content-Length:表示请求消息正文的长度。例如:Content-Length: 38。
  • x-requested-with: XMLHttpRequest 这个的话娿表示是请求来自ajax, 蛮有意思的:记得在laravel框架里面出现了表单验证错误,ajax请求会返回json数据,非ajax返回重定向或者页面之类的

HTTP常见的响应头

  • Allow:服务器支持哪些请求方法(如GET、POST等)
  • Date:表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦
  • Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它,重新从服务器获取,会更新缓存。过期之前使用本地缓存。HTTP1.1的客户端和缓存会将非法的日期格式(包括0)看作已经过期。eg:为了让浏览器不要缓存页面,我们也可以将Expires实体报头域,设置为0。
  • P3P:用于跨域设置Cookie, 这样可以解决iframe跨域访问cookie的问题
  • Set-Cookie:非常重要的header, 用于把cookie发送到客户端浏览器 例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com
  • ETag:和If-None-Match 配合使用。
  • Last-Modified:用于指示资源的最后修改日期和时间。Last-Modified也可用setDateHeader方法来设置。
  • Content-Type: 请求体的MIME类型
  • Content-Length:指明实体正文的长度,以字节方式存储的十进制数字来表示。
  • Content-Encoding:WEB服务器表明自己使用了什么压缩方法
  • Server:指明HTTP服务器用来处理请求的软件信息。这个在nginx里面见过,谷歌的server写的是server:gws
  • Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader(“Refresh”, “5; URL=http://host/path”)让浏览器跳转到指定的页面。 HTML页面HEAD区的
    <META HTTP-EQUIV=”Refresh” CONTENT=”5;URL=http://host/path”>,如果URl是本页面的地址的话,还能实现自动刷新
  • Content-Disposition 对已知MIME类型资源的描述,浏览器可以根据这个响应头决定是对返回资源的动作,如:将其下载或是打开。Content-Disposition: attachment; filename=”fname.ext”

关于Content-Type

The Content-Type entity header is used to indicate the media type of the resource. Content-Type 实体头部用于指示资源的MIME类型(媒体类型) 。

  • application/octet-stream 二进制流,不知道下载文件类型
  • text/html html
  • application/x-www-form-urlencoded 浏览器的原生 form 表单 长这个逼样title=test&name=feng
  • multipart/form-data

该种方式也是一个常见的 POST 提交方式,通常表单上传文件时使用该种方式。这个稍微帅气了一点

请求头上跟了个boundary标识分隔符 例如: Content-Type: multipart/form-data; boundary=—-WebKitFormBoundaryoEGJSBxGz2leU0Vv

ody 里字段分多个部分,每部分以 –boundary 开始,然后是内容描述信息,回车空行(CRLF)之后是字段的具体内容,内容可以是文本或者二进制形式。如果传输文件,需要包含文件名和文件类型信息。最后加上–表示数据结束。

 

 

  • application/json

主体是序列化后的 JSON 字符串


本文只做镜像和学习之用,原文地址链接:地址

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注