上图为一个典型的HTTP请求报文,包含
请求行:第一行。 POST /api/v1/ping HTTP/1.1 POST是请求方法,同时还有GET/CONNECT等等。 /api/v1/ping是资源标识符URI。 HTTP/1.1表明该报文遵循HTTP1.1版本的规范。请求头:第二行一直到空行的部分。请求主体(Body):以一个空行与头部相隔。 报文中携带的信息,比如即将更新的资源信息等等。根据这里。
译自这里。 HTTP中URI有三种形式:
* 单个?号只有在请求并不指向某个特定的资源,而是指向服务器时使用。并且只能是在Method并不是必须指向某个资源时使用,比如可以在OPTION方法中使用,但是GET就不可以了。 For example: OPTIONS * HTTP/1.1绝对路径 绝对路径会在请求指向代理时使用。代理服务器会将请求或服务从一个有效的缓存中转发,并返回一个响应。 For example: GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1相对路径 这是最常见的URI形式,可以从一个服务器或网关定位到资源。相对路径形式的URI都带有Host来表示主机地址。 For example: GET /pub/WWW/TheProject.html HTTP/1.1 Host: www.w3.orgURL是一种URI,是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上。 一个常见的URL如下: http默认端口为80,https默认端口为443
这是一个典型的chrome浏览器发送请求时所带的Header.
Mozilla/5.0 。Mozilla是一个上古公司(远景)开源的第一个开源浏览器,之后所有浏览器或多或少都带有其代码,因此现今浏览器User-Agent的第一行一般都是这个,为了伪装成Mozilla。标识客户端操作系统。Webkit是Apple公司开源的浏览器引擎,与之相对应的引擎有Gecko(Mozilla Firefox 等使用)和Trident(也称MSHTML,IE 使用)。这一行有点历史渊源,KHTML和Gecko都是很好的引擎。标识浏览器为Chrome我的浏览器明明是Chrome,为什么会带有Apple的Safari?事实上,safari是在Chrome浏览器之前推出的,它使用了自家的Webkit引擎,效果也很好。后来Chrome推出的时候也用了Webkit,为了能更好地渲染那些为safari而写的网页,Chrome就在自己的User-Agent里加上Safari来伪装成Safari。And then Google built Chrome, and Chrome used Webkit, and it was like Safari, and wanted pages built for Safari, and so pretended to be Safari. And thus Chrome used WebKit, and pretended to be Safari, and WebKit pretended to be KHTML, and KHTML pretended to be Gecko, and all browsers pretended to be Mozilla, and Chrome called itself Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13, and the user agent string was a complete mess, and near useless, and everyone pretended to be everyone else, and confusion abounded.
This is funny,可能后面会出现一个新的开源浏览器,在其UA中加入Chrome来伪装成Chrome。
根据这里
HTTP协议是基于TCP协议进行传输的,如果每传输一次HTTP协议的报文,都进行来一次TCP连接的建立与断开,那么就会进行很多次的三次握手、四次挥手。当进行连续的HTTP协议传输时,显然产生了许多不必要的等待时间(主要集中在TIME_WAIT)。于是就提出了在一次TCP连接中进行多次HTTP报文的交换。以此提高性能和提高httpd服务器的吞吐率。
Note:滥用keep-alive会导致闲置的tcp连接消耗系统资源,须配置合理的keep-alive timeout。 Note:启用keep-alive需要请求报文中表明希望建立keep-alive,同时服务器响应报文中表明同意建立keep-alive连接。 Note:需配合Content-Length使用。 keep-alive timeout,即一个TCP连接中,最长等待HTTP报文的时间。即TCP发送完一个响应后,若keep-alive timeout时间内没有新的请求进来,才会选择关闭TCP连接。
表示可接受的响应的编码形式。
根据这里
1xx:指示信息–表示请求已接收,继续处理 2xx:成功–表示请求已被成功接收、理解、接受 3xx:重定向–要完成请求必须进行更进一步的操作 4xx:客户端错误–请求有语法错误或请求无法实现 5xx:服务器端错误–服务器未能实现合法的请求
常见状态码:
200 OK //客户端请求成功 400 Bad Request //客户端请求有语法错误,不能被服务器所理解 401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 403 Forbidden //服务器收到请求,但是拒绝提供服务 404 Not Found //请求资源不存在,eg:输入了错误的URL 500 Internal Server Error //服务器发生不可预期的错误 503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
全部状态码:
根据这里
(二进制分帧、多路复用):HTTP 2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。每个消息拆分为多个帧,每帧用一个id表示序号,乱序发送,然后根据id组装,以此提升效率。(二进制分帧、多路复用)(头部压缩):HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。(服务器推送):服务器除了对最初请求的响应外,服务器还可以额外的向客户端推送资源,而无需客户端明确的请求。进一步了解
进一步了解
在HTTP 1.1时代,通过使用keep-alive技术来增加传输效率,然而这种方式也是有瓶颈的。当多个资源想要同时发送到相同的目的地时(比如服务器需要发送多个图片到客户端),后面来的图片流stream必须等前面的图片流stream完成传输后才能进行。如果队伍第一个stream流发生阻塞,那么后面队伍后面的stream都将被阻塞。这是一种被叫做head-of-line (HOL)的阻塞,在HTTP 1.1中是一个优化难题。一种缓解方法是开多个TCP连接,但是通常浏览器都会限制TCP连接的数量,同时开新TCP连接也会发生系统资源的消耗。
在HTTP2.0中,这个问题被很好地解决了。 HTTP 2.0将所有的stream流的消息都分割成一个个帧,并编码为二进制。每个帧有一个标头,其中包含帧的长度和类型、一些布尔标志、一个保留位和一个流标识符。所有的帧都放在一个TCP上乱序传输,同时另一端再根据帧头部序号将它组装起来。
Note:帧还有优先级,来保证某些资源的优先传输。 通过分帧,达到来多路复用的目的,同时大大加快来传输效率。
使用分帧的好处:
可以并行交错地发送stream流,各个流之间不会相互干扰。服务器端和客户端可以同时发送请求,不必等待只使用一个TCP连接即可并行发送多个请求和响应;单个TCP连接可以提高HTTPS协议的性能,因为客户端和服务器可以将相同的Session复用于多个请求/响应。分帧可以达到多路复用的目的,那么将信息转化为二进制编码的目的是什么?
事实上,二进制编码与字符串编码并没有绝对上的 ”谁更好,谁更差“。两种编码适用于不同情况,字符串编码面向的是文本信息,产生的是可读的信息,而二进制编码面向的是机器,在不考虑可读性的情况下可能具有更好的压缩性等。
在以下两种情况下,二进制编码将拥有更好的性能:
Numbers 数字: 比如,传输15, 字符串编码为 ASCII for char ‘1’: 00110001 ASCII for char ‘5’: 00110101 而二进制编码为00001111Data Structures 数据结构(图片、视频等): 用字符串编码来传输数据结构,将难以处理开头和结尾。而具有固定长度字段的二进制编码会更紧凑。显然,HTTP中的头也属于一种数据结构。 比如:
GET /files/image.jpg HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/4.01 [en] (Win95; I) Host: hal.etc.com.au Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, / Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8
若作为数据结构存储,则表示为:
struct request { int requestType; int protocolVersion; char path[1024]; char user_agent[1024]; char host[1024]; long int accept_bitmask; long int language_bitmask; long int charset_bitmask; };
显然,二进制编码的形式更好处理,同时也具有更好的压缩性(因其不用再携带字段名称,只用携带字段值)。因此,对于HTTP协议的情况,底层使用二进制编码传输比字符串传输更好。
Note:两端收到二进制信息会重新转化为字符串再交予web服务器。
还有一处总结:
HTTP2.0中使用二进制的优点:
二进制编码协议解析效率更高二进制编码压缩率更高,在网络传输过程中具有更高的效率与HTTP1.1相比。HTTP1.1中具有大量处理空白、大写、行尾的辅助函数,因此复杂度更高,处理起来更容易出错。更加安全,因为与文本攻击(例如拆分)相关的安全问题将不再发生。参考1 参考2 参考3 参考4 参考5
Q:keep-alive 的情况下,服务器端如何判断进入到了下一个报文? A:每一个报文的Content-Length表明了报文Body的长度,以此来判断是否读完当前报文。
Q:在浏览器地址栏键入URL后敲击回车会发生什么? A:
浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接; (如果是https,则使用443端口)浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;服务器对浏览器请求作出响应,并把对应的资源发送给浏览器。如果启用keep-alive,则服务器继续等待接受请求报文,客户端则继续发送请求报文,否则服务器端主动关闭TCP连接,客户端被动关闭连接。浏览器将获得的资源返回给用户,如果是HTML文件,则渲染在浏览器中。Q:GET与POST的区别? A:
GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.Q:为什么不抛弃GET方法? A: 根据这里
他们的语义不同,代表着主干网络可以对他们进行不同的处理。
GET表达的是一种只读的操作,即它除了返回结果不应该会产生其它副作用。因此绝大部分get请求(通常超过90%)都直接被CDN缓存了,这能大大减少web服务器的负担。而POST请求可能带有写操作,因此必须交给web服务器进行处理。以上所有内容均为本人道听途说,胡乱编写,东拼西凑而成 如果侵权,请联系我删除 如果你发现了我的错误,请留言帮助我改正。十分感谢? All of the above are all hearsay If infringed, please contact me to delete If you find my mistake, please leave a message to help me correct it. Thank you very much?
