本文参考资源:
https://danielmiessler.com/study/url-uri/
http://www.cnblogs.com/xing901022/p/4309840.html
http://blog.csdn.net/a19881029/article/details/14002273
http://www.mamicode.com/info-detail-1357508.html
http://blog.csdn.net/sinat_21455985/article/details/53508115
1. 什么是HTTP
HTTP(hypertext transfer protocol) 也就是超文本传输协议,简单来说HTTP协议是万维网的基础。 HTTP是一种在client-server计算机模型中的请求—响应的协议。例如,现在有一个运行在server端的web应用程序,客户端向服务器提交一个HTTP请求消息。服务器就会向客户端响应如HTML文件和其他内容之类的资源,响应包含关于请求的完成状态信息,并且可能还在其消息体中中包含的其他的请求内容。而浏览器就是一种类型的client, 其他的client还包括搜索提供的程序,例如web爬虫,语音浏览器,移动应用程序或者其他显示web内容的软件。HTTP是在Internet协议套件框架内设计的一种应用层协议。它的定义假定有一个可靠的传输层协议,传输控制协议(TCP)通常被使用。然而,HTTP可以被改编成使用不可靠的协议,例如用户数据报协议(UDP),例如HTTP pu和简单的服务发现协议(SSDP)。
HTTP协议是用于从WWW服务器传输超文本到本地浏览器的传送协议
2. HTTP协议
HTTP协议是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型,HTTP是一个无状态的协议。
2.1 HTTP在TCP/IP协议栈中的位置
HTTP协议承载在TCP协议之上,有时候也承载于TLS或者SSL协议层之上,这个时候就成了HTTPS。
如图:
默认HTTP端口是80,或者HTTPS端口为443
2.2. 什么是URL和URI
URI: 统一资源标识符:是一个单纯的字符串用来把某一个资源唯一的标识出来,例如人的身份证号码。
URL:统一资源定位符:URL标识某一个资源唯一位置,例如身份证上的地址,所以由此可发现,URL是URI的一个子集。 除了确定一个资源,还提供了一种定位资源的访问机制,例如ftp,http等,所以要把一个一个URI编程一个URL的就是这个访问机制。
URI和URL的关系如下:
例如:
ftp://ftp.is.co.za/rfc/rfc1808.txt 也是一个URL,因为提供了ftp访问机制
http://www.ietf.org/rfc/rfc289.txt 也是一个URL ,因为提供了http访问机制
tel:+1-932-333-123 URI
urn:oasis:names:specification:docbook URI
所以对于一个WEB地址来说,可以说是一个URI,也可以说是一个URL因为它提供了访问机制。
3. 一次完整HTTP请求全过程
step1: 浏览器会查找这个域名的IP地址,即域名解析
例如访问: www.baidu.com, 浏览器会先解析这个域名对应的IP地址
- 浏览器会首先搜索浏览器自身的DNS缓存,看自身的缓存是否存在www.baidu.com对应的条目,是否过期,如果有且没有过期,那么解析到此结束
- 如果浏览器自身的缓存里面没有找到对应的条目,那么浏览器会搜索操作字体自身的DNS缓存,如果找到且没有过期,则搜索解析到此结束
- 如果在windows操作系统的DNS缓存也没有找到,那么尝试读取hosts文件(c:\windows\system32\drivers\etc),看这里是否有该域名的IP地址,如果有则解析成功
- 如果在host里面没有找到对应的条目,浏览器就会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器(一般电信运营商提供)发起域名解析请求。
域名解析的方式主要分两种:
或者:
step2:发起TCP的三次握手。
拿到对应的IP地址之后,User-Agent(一般是浏览器)会以一个随机端口向服务器请求web程序,80端口发起TCP连接请求,最后请求到达WEB服务器。之所以要先建立TCP连接是因为在HTTP工作之前需要先和服务器建立连接,该连接是通过TCP完成的,HTTP是比TCP更高层的协议,所以只有TCP协议建立之后才能进行HTTP连接。
step3: TCP连接建立完成之后,浏览器会发送一个HTTP请求到web server,例如是访问facebook主页, HTTP请求报文包括:请求行<request-line>,请求头部<headers>,空行<blank-line>和请求数据<request-body>
step4: web服务器响应HTTP请求,浏览器得到HTML代码
服务器端WEB程序接收到HTTP请求之后,就开始处理该请求,处理完成之后会返回浏览器HTML文件。
step5: 浏览器解析HTML代码,并且请求HTML代码中的资源(js,css,图片等)
浏览器拿到 index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端请求下载,这个时候就用上keep-alive特性,建立一次HTTP连接,可以请求多个资源。
浏览器在请求静态资源时(在未过期的情况下),向服务器发起一个HTTP请求(询问自从上一次修改时间到下载有没有对资源进行修改),如果服务端返回304状态码,(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地资源的缓存文件。
step6: 浏览器对页面进行渲染呈现给用户
浏览器利用自己内部的工作机制,把请求到的静态资源和HTML代码进行渲染,然后呈现给用户。
step7: 传输完成,断开四次挥手
4. HTTP报文
HTTP报文包括:报文头部,空行(CR+LF),报文主体
空行用来区分报文头部和报文主题,无论是请求报文还是响应报文都需要报文头部,但是报文主题有些请求报文是没有的。
4.1 请求报文格式:
- 请求行
请求行包括:请求方法,URI,以及协议版本,他们用空格分隔。
请求方法包括例如GET,POST等,协议版本格式为:HTTP/主版本号.次版本号,常用的有HTTP/1.0和HTTP/1.1
例如:GET /index.html HTTP/1.1
- 请求头部
请求头部为请求报文添加了附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔
常见请求头部有:
host: 接受请求的服务器地址,可以是IP:端口号,也可以是域名
User-Agent: 发送请求的应用程序名称,一般是浏览器
Connection:指定与连接相关的属性,如:Connection:Keep-Alive
Accept-Charset: 通知服务端可以发送的编码格式
Accept-Encoding:通知服务端可以发送的数据压缩格式
Accept-Language: 通知服务端可以发送的语言
Accept: 告诉服务器接受哪些MIME类型
Cookie:每次请求都会携带上Cookie以方便服务器识别是否是同一个客户端
请求头部最后一个空行标识请求头部结束
- 请求正文
可选部分,比如,GET就没有请求正文
4.2 HTTP响应报文格式
HTTP响应报文主要包括:状态行,响应头部,响应正文3部分组成
- 状态行
由三部分组成:协议版本,状态码,状态码描述
- 响应头部
与请求头部相似。也是由关键字/值组成,每行一列,关键字和值用英文冒号隔开。一般响应头部有:
Server: 包含服务器用来处理请求信息的软件信息以及版本,和User-Agent请求的报文头是相对应的,前者发送服务器软件信息,后者发送客户端软件和操作系统信息。
Location: 用于重定向接收者到一个新的位置,例如:客户端请求的页面已经不存在原先的位置,为了让客户端重定向到这个新的页面位置,服务器端可以发回location响应报头后使用重定向语句,让客户端访问新的域名所对应的服务器资源。
Vary: 指示不可缓存的请求头部列表
connection:连接方式
- 对于请求来说: close告诉web服务器或者代理服务器,在完成本次请求响应后,断开连接,不等待本次连接的后续请求了,keep-alive告诉服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求
- 对于响应来说: close标识连接已经关闭,keep-alive标识连接抱持着,在等待本次连接的后续请求, keep-alive:如果浏览器请求保持连接,则该头部表明希望WEB服务器保持连接多长时间,例如:keep-alive 300s
Content-Type: 响应正文的类型(图片或者二进制字符串)
Content- Length: 响应正文的长度
Content-Charset: 响应正文的编码
Content- Encoding: 响应正文使用的数据压缩格式
Content-Language: 响应正文使用的语言
- 响应正文
服务器返回给客户端的数据
5. HTTP请求类型
- GET:从指定的服务器中获取数据
请求获取由Request-URI所标识的资源, 当客户端需要从服务器读取文档时,当点击网页上的连接或者通过浏览器的地址栏输入网站来浏览网页时, 使用的都是GET, GET方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。使用GET方法时,请求参数和对应的值附加在URL后面,利用一个问号(?)代表URL的结尾与请求参数的开始,传递参数的长度受限制,例如: /index.jsp?id=100&op=bind , 通过GET方式传递的数据直接放在地址中,所以GET方式的请求一般步包含‘请求正文’部分,请求数据以地址形式表现在请求行,地址中的?之后的部分就是通过GET发送的请求数据,可以在地址栏中看到,各个数据用&隔开,例如:https://www.baidu.com?swd=http%E6%8A095e=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8, 很显然这种方式不适合传送私密数据,另外不同的浏览器对地址的字符限制也不一样,一般最多只能识别1024个字符,所以需要传递大量数据的时候也不适合使用GET,如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD$A0%E5, 其中%XX中的XX为该符号以16进制标识的ASCII。
GET特点:
GET请求能被缓存
GET请求会保存在浏览器的记录中
GET请求数据有长度限制
GET主要用于获取数据
-POST:提交数据给指定的服务器处理,post也有GET的功能
post方法将请求参数封装在HTTP请求的请求正文中,以名称/值的形式出现, 可以传输大量数据,这样POST方式对传输的数据大小没有限制,而且也不会显示在URL中,POST方式请求行中不包含数据字符串,这些数据保存在‘请求正文’中,各个数据也用&隔开,POST方式大都用于页面的表单中。
POST特点:
POST请求不能被缓存下来
POST请求不会保存在浏览器记录中
POST请求没有长度限制
-HEAD: HEAD就像是GET,只不过服务器接收到的HEAD请求后只返回响应头,而不会发送响应内容,所以如果只需要查看某个页面的状态的时候,就可以使用HEAD
-PUT: 用于更新某个资源较完整的内容,例如用户要填完整个表单的所有信息,后台处理更新时可能只是保留内部记录ID不变。只能对已有的资源进行更新操作,所以是UPDATE操作
- PATCH:用于资源的部分内容更新,比如一个字段,具体说比如更新某个用户信息的电话号码字段。
-DELETE:删除URL上指定的资源
200- 删除成功,同时返回已经删除的资源
202- 删除请求已经接受,但是没有被例即执行(资源也许已经被转移到了待删除区域)
204- 删除请求已经执行,但是没有资源返回,也是是请求删除不存在的资源造成的。
-POTIONS: 允许客户端查看服务器的性能
-TRACE: 回显服务器受到的请求,主要用于测试或者诊断
6. HTTP响应状态码
HTTP响应状态码由三位数组成,200-299标识成功,300-399标识资源重定向,400-499标识客户端出错,500-599标识服务端出错,100-199信息性状态码。
1xx: 信息性状态码,例如:100,101
2xx: 成功状态码 200:OK
3xx: 重定向状态码
- 301:永久重定向,location响应首部的值依然是当前的URI,所以是隐藏重定向
- 302 :临时重定向,显示重定向,Location响应首部的值为新的URI
- 304 :Not Modified ,未修改,比如本地缓存的资源文件和服务器上比较时,发现没有修改,服务器范围一个304状态码,告诉浏览器,不用请求资源,直接使用本地资源。
4xx: 客户端错误状态码
- 400 客户端请求有语法错误,不能被服务器识别
- 403: 服务器接受到请求,但是拒绝服务,(认证错误)
- 404: Not Found, 请求的URI资源不存在
5xx: 服务器端错误状态码
- 500: Internal Server Error 服务器内部错误
- 502 : Bad Gateway 前面代理服务器联系不到后端的服务器时出现
-504 :Gateway timeout 这个是代理能联系到后端服务器,但是后端的服务器在规定的时候没有给代理服务器响应
6. 如何查看HTTP请求
例如CHROME浏览器:开发者工具->Network
或者使用抓包工具Fiddler