1、什么是HTTP协议?
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的简称,是用于从万维网(WWW)传输超文本到本地浏览器的传输协议。 它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
HTTP是一个应用层协议,由请求和响应组成,是一个标准的客户端服务器架构(C/S)的协议。HTTP还是一个无状态协议。
HTTP协议工作于客户端-服务端架构之上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送请求。Web服务器根据接收到的请求后,向客户端发送响应信息。下图所示是HTTP的请求-响应模型示意图。
HTTP的请求-响应模型限制了服务器无法在客户端没有请求的时候主动推送消息给客户端。并且HTTP协议是一个无状态协议,即同一个客户端上一次请求和下一次请求之间没有任何关联。
HTTP基于TCP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。安全版本的HTTPS基于TLS或SSL
HTTP默认端口80,HTTPS默认端口443。
2、HTTP协议工作过程
一次HTTP操作工作过程可分为四步:
(1)客户端的浏览器与服务器建立连接。只要单击某个超级链接,HTTP的工作开始。
(2)连接建立之后,客户端首先给服务器发送一个请求。请求的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容
(3)服务器接收到请求之后给与响应。响应消息的格式为:一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
(4)客户单接收到服务器返回的消息并通过浏览器显示在屏幕上,然后客户机与服务器断开连接。
如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,由显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。
3、HTTP协议状态响应码
一般无论此次请求是否成功响应,服务器都会返回一个状态响应码,HTTP协议中定义了诸多状态码,按照原因可以划分为5大类,如下图所示。
- 常见状态码含义:
200 (OK):服务器成功处理了请求。
204(NOT Content):服务器成功处理了请求,但没有返回任何内容
301(Moved Permanently):永久性重定向。表示请求的资源已被分配了新的 URI。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置
302(Found):临时性重定向。表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。和 301 Moved Permanently 状态码相似,但 302 Found 状态码代表资源不是被永久移动,只是临时性质的。换句话说,已移动的资源对应的 URI 将来还有可能发生改变。
304(Not Modified):表示客户端发送附带条件的请求时,服务器端允许请求访问的资源,但未满足条件的情况。
400(Bad Request):表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
401(Unauthorized):请求要求身份验证。对于登录后请求的网页,服务器可能返回此响应。
403(Forbidden):服务器拒绝请求
404(Not Found):表明服务器上无法找到请求的资源。
405(Method Not Allowed ):请求的资源不支持请求使用的方法
414 (Request-URI Too Large):请求参数参数过长
500(Internal Server Error):服务器内部错误,服务器在处理请求的时候出现错误。
501(Not Implemented) :服务器不认识或不支持的请求使用的方法
502(Bad Gateway):错误网关
503(Service Unavailable):服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
504(Gateway Timeout):网关超时,由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。
505(HTTP Version Not Supported):服务器不支持请求中所指明的HTTP版本。
4、HTTP协议消息结构
(1)客户端请求消息
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头(request header)、空行(\r\n)和请求数据。
使用Wireshark抓包分析:
(2)服务器响应消息
HTTP响应数据也有4个部分:状态行、消息头部、空行(\r\n)和响应正文。
使用Wireshark抓包分析:
5、HTTP请求方法
HTTP 协议中共定义了8种方法或者叫“动作”来表明对 Request-URI 指定的资源的不同操作方式,具体介绍如下:
HTTP/1.0定义了三种请求方法:GET、POST和HEAD
HTTP/1.1在新增了五种请求方法:DELETE、PUT、OPTIONS、TRACE和CONNECT
八种方法具体含义如下:
序号 | 方法 | 描述 |
---|---|---|
1 | GET | 向特定的资源发出请求。请求参数数据都在url中 |
2 | HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件),请求数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 向指定资源位置上传其最新内容 |
5 | DELETE | 请求服务器删除指定的内容。 |
6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
注意: 1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。 2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。
6、GET、POST的区别?
打开浏览器,我们输入“GET、POST的区别” 查询出来的答案大致如下:(具体参考W3CSchool:HTTP 方法:GET 对比 POST):
- GET请求的URL长度是有限制的(不同的浏览器和服务器限制不同),但是POST请求没有限制;
- GET请求比POST请求更安全,因为GET请求的参数就在URL中,当时POST请求的请求参数在请求体中;
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制;
- GET请求参数会被完整保留在浏览器历史记录里;相反,POST请求参数不会被浏览器保留;
- GET请求只能进行url编码(application/x-www-form-urlencoded),而POST支持多种编码方式;
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置;
- GET在浏览器回退时是无害的,而POST会再次提交请求。
除了上面在W3CSchool这篇文章中提到的区别,在网上还有一种区别也来总结一下:
GET产生一个TCP数据包;POST产生两个TCP数据包。
具体说就是:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
7、GET请求有Resuqest Body吗?POST请求可以把请求参数写在URL里吗?
先给出答案:GET请求有请求体并且可以将请求参数放到请求体中;POST请求也可以将请求参数写到URL上;
其实GET和POST在本质上没有区别,都是HTTP协议中的两种发送请求的方法。而HTTP呢,是基于TCP/IP的关于数据如何在万维网中如何通信的协议。
HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。
GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
HTTP只是个行为准则,而GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
8、URL中传送参数的长度在Get和Post中的限制
这一块其实不是HTTP协议本身的限制,而是不同厂家实现浏览器或服务器的限制,原因很简单:数据量太大对浏览器和服务器都是很大负担。
业界不成文的规定是,大多数浏览器通常都会限制url长度在2K~8K字节,而大多数服务器最多处理64K大小的url。
超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略。
所以,虽然GET可以带request body,却不能保证一定能被接收到。
9、POST 方法比 GET 方法更安全?
从表面上看,GET请求的参数直接在URL中,在地址栏中可以直接看得见,POST的请求参数在请求体中,似乎更安全。
从传输角度看,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上抓包,就能完整地获取数据报文。因此想要安全传输,就只有加密,也就是 HTTPS。
现在,当面试官再问你“GET与POST的区别”的时候,你的内心是不是这样的?
参考资料
- [1] 听我讲完GET、POST原理,面试官给我倒了杯卡布奇诺
- [2] GET请求中URL的最大长度限制总结
- [3] get 和 post 请求有哪些区别?
- [4] 菜鸟教程:HTTP教程