了解HTTP协议,这一篇就够了
HTTP(Hyper Text Transfer Protocol:超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。
HTTP协议的主要特点可概括如下:
-
支持客户/服务器模式。
-
简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
-
灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
-
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
-
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP协议–URL
HTTP URL (URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息)的格式如下:
http://host[“:”port][abs_path]
http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用缺省端口80;abs_path指定请求资源的URI;如果URL中没有给出abs_path,那么当它作为请求URI时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。
eg:
1、输入:www.baidu.com
浏览器自动转换成:http://www.baidu.com
2、http://127.0.0.1:8080/login.html
HTTP协议–工作过程
一次HTTP操作称为一个事务,其工作整个过程如下:
-
地址解析
如用客户端浏览器请求这个页面:http://localhost.com:8080/index.htm
从中分解出协议名、主机名、端口、对象路径等部分,对于我们的这个地址,解析得到的结果如下:
协议名:http
主机名:localhost.com
端口:8080
对象路径:/index.htm
在这一步,需要域名系统DNS解析域名localhost.com,得主机的IP地址。
2)封装HTTP请求数据包
把以上部分结合本机自己的信息,封装成一个HTTP请求数据包
3)封装成TCP包,建立TCP连接(TCP的三次握手)
在HTTP工作开始之前,客户机(Web浏览器)首先要通过网络与服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能进行更高层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。这里是8080端口
4)客户机发送请求命令
建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URI:Uniform Resource Identifier)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容
5)服务器响应
服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
实体消息是服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
6)服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码
Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
HTTP协议–请求方法
HTTP请求方法有多种,各个方法的解释如下:
-
GET:获取资源
GET方法用来请求访问已被URI识别的资源。也就是指定了服务器处理请求之后响应的内容以?分割URL和传输数据,参数之间以&相连
Eg : http://dev-his.seenew.info/newDoctorStation/StationLayoutEdit?k=123551-23-XN900128&tem=495&edit=false
-
POST:传输实体主体
POST方法用来传输实体主体。POST与GET的区别之一就是目的不同,虽然GET方法也可以传输,但是一般不用,因为GET的目的是获取,POST的目的是传输。
-
PUT:传输文件
PUT方法用来传输文件。类似FTP协议,文件内容包含在请求报文的实体中,然后请求保存到URL指定的服务器位置。
-
HEAD:获得报文首部
HEAD方法类似GET方法,但是不同的是HEAD方法不要求返回数据。用于确认URI的有效性及资源更新时间等。
-
DELETE:删除文件
DELETE方法用来删除文件,是与PUT相反的方法。DELETE是要求返回URL指定的资源。
-
OPTIONS:询问支持的方法
因为并不是所有的服务器都支持规定的方法,为了安全有些服务器可能会禁止掉一些方法例如DELETE、PUT等。那么OPTIONS就是用来询问服务器支持的方法。
-
TRACE:追踪路径
TRACE方法是让Web服务器将之前的请求通信环回给客户端的方法。这个方法并不常用。
-
CONNECT:要求用隧道协议连接代理
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL/TLS协议对通信内容加密后传输。
GET和POST区别
-
GET和POST都是客户端向服务器发送请求的一种方法
-
GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,POST方法是把提交的数据放在HTTP包的Body中。eg: http://dev-his.seenew.info/newDoctorStation/StationLayoutEdit?k=123551-23-XN900128&tem=495&edit=false
-
GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
-
GET提交的数据大小有限制,最多只能有1024字节(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制。
-
安全性:
-
GET就像查询一样,只读不写不更改资源,POST是向服务器提交数据,提交后,资源已经发生变化
-
GET的请求数据附在URL后面,可以在地址栏看到,如果浏览器不清除记录,容易被人获取到账号密码,而POST是把提交的数据放在实体主体中的,一般用户端(web)无法查看,所以相对来说安全点
-
GET提交的请求,数字和英文,会原样发送,如果是空格,会转换成+,如果是中文或者其他字符,需要用base64加密(如果是+,容易被拦截)得到类似于%E4%BD%A0%E5%A5%BD这样的数据
HTTP协议–响应状态码
接收和解释请求消息后,服务器返回一个HTTP响应消息。
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
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协议–请求报头
请求报头(Request Headers):
常用的请求报头
-
Accept
Accept请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:application/json ,表明客户端希望接受josn格式的资源;Accept:text/html,表明客户端希望接受html文本。
-
Accept-Charset
Accept-Charset请求报头域用于指定客户端接受的字符集。eg:Accept-Charset:iso-8859-1,gb2312.如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。
-
Accept-Encoding
Accept-Encoding请求报头域类似于Accept,但是它是用于指定可接受的内容编码。eg:Accept-Encoding:gzip.deflate.如果请求消息中没有设置这个域服务器假定客户端对各种内容编码都可以接受。
-
Accept-Language
Accept-Language请求报头域类似于Accept,但是它是用于指定一种自然语言。eg:Accept-Language:zh-cn.如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。
-
Authorization
Authorization请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。eg:Bearer 4dfc0a15-0ce1-43a1-9bed-3b09e5363f8d
-
Host(发送请求时,该报头域是必需的)
Host请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的
-
Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
-
Connection:表示是否需要持久连接。如果Servlet看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小;
-
Cache-Control:指定请求和响应遵循的缓存机制。
-
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消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
-
Content-Length:表示请求消息正文的长度;
-
Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝
-
Content-Type:标明发送或者接收的实体的MIME类型。Eg:text/html; charset=GB2312 主类型/子类型;
Eg:application/json; charset=UTF-8
-
Origin:标识跨域资源请求(请求服务端设置Access-Control-Allow-Origin响应字段)
-
User-Agent
User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。不过,这个报头域不是必需的,如果我们自己编写一个浏览器,不使用User-Agent请求报头域,那么服务器端就无法得知我们的信息了。
Eg:
POST /app-station-manage/orderCommon/listDict HTTP/1.1
Host: xxxxxxxxxxxxxx
Connection: keep-alive
Content-Length: 40
Pragma: no-cache
Cache-Control: no-cache
k2: 23
Origin:xxxxxxxxx
Authorization: Bearer 4dfc0a15-0ce1-43a1-9bed-3b09e5363f8d
Content-Type: application/json; charset=UTF-8
Accept: application/json
k1: xxxxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Referer:http:xxxxxxxxxxxx
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
HTTP协议–响应报头
-
Access-Control-Allow-Methods: 服务器支持哪些请求方法
-
Date:表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦
-
Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它,重新从服务器获取,会更新缓存。过期之前使用本地缓存。HTTP1.1的客户端和缓存会将非法的日期格式(包括0)看作已经过期。eg:为了让浏览器不要缓存页面,我们也可以将Expires实体报头域,设置为0。
-
Transfer-Encoding:告知接收端,报文采取了何种编码,chunked表示服务器无法确定消息大小,一般比如下载等,就采用chunked。X-Application-Context: application配置,这里表示读取的是application-prod.properties
-
X-Content-Type-Options: 是用来禁用浏览器内容嗅探行为。
nosniff
下面两种情况的请求将被阻止:
请求类型是”style” 但是 MIME 类型不是 “text/css”,
请求类型是”script” 但是 MIME 类型不是 JavaScript MIME 类型。
-
Server:首部包含了处理请求的源头服务器所用到的软件相关信息。
-
X-Frame-Options:
用来给浏览器指示允许一个页面可否在 <frame>, <iframe> 或者 <object> 中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击
DENY
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
SAMEORIGIN
表示该页面可以在相同域名页面的 frame 中展示。
ALLOW-FROM uri
表示该页面可以在指定来源的 frame 中展示。
-
X-XSS-Protection:
响应头是Internet Explorer,Chrome和Safari的一个功能,当检测到跨站脚本攻击 (XSS)时,浏览器将停止加载页面。虽然这些保护在现代浏览器中基本上是不必要的,当网站实施一个强大的Content-Security-Policy来禁用内联的JavaScript (\’unsafe-inline\’)时, 他们仍然可以为尚不支持 CSP 的旧版浏览器的用户提供保护。
X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>
-
0
禁止XSS过滤。
-
1
启用XSS过滤(通常浏览器是默认的)。如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部分)。
-
1;mode=block
启用XSS过滤。如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载。
-
1; report=<reporting-URI> (Chromium only)
启用XSS过滤。如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri指令的功能发送违规报告。
Eg:
HTTP/1.1 200
Server: nginx/1.14.2
Date: Thu, 20 Jun 2019 11:15:29 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
X-Application-Context: app-station-manage:dev:8414
Access-Control-Allow-Methods: GET, POST, OPTIONS