【网络学习笔记】HTTP基础知识点 2018.09.19 ---转
简单请求(simple request)和非简单请求(not-so-simple request)。
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时满足以下两大条件,就属于简单请求。
(1) 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
(2)HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。对于简单请求,浏览器直接发出CORS请求。
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT
或DELETE
,或者Content-Type
字段的类型是application/json
。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
目录
HTTP
协议是很基础但又很容易被忽略的知识。本篇文章整理了HTTP
协议相关的基础知识点,适合入门学习的同学。
网络基础
计算机网络协十分复杂,为了让复杂的网络简单化,专家们对网络协议进行了分层。
常见的两种分层方式:
OSI
模型TCP/IP
协议
OSI
模型
OSI模型(Open System Interconnection,OSI/RM,Open Systems Interconnection Reference Model),即开放式通信系统互联参考模型,是国际标准化组织(ISO)提出的一个试图使各种计算机在世界范围内互连为网络的标准框架。
OSI将[计算机网络体系结构(architecture)划分为以下七层:
分层 | 每层的操作 |
---|---|
应用层 | 在数据前面加首部,首部包括数据内容、源地址和目标地址,同时也会处理异常的反馈信息。 |
表示层 | 将特有的数据格式转换为通用的数据格式,同时也会加上表示层的首部信息以供解析。 |
会话层 | 对何时连接,以何种方式连接,连接多久,何时断开等做记录。同时也会加会话层的首部信息。 |
传输层 | 建立连接,断开连接,确认数据是否发送成功和执行失败重发任务。 |
网络层 | 负责将数据发到目标地址,也包含首部信息。 |
数据链路层 | 通过物理的传输介质实现数据的传输。 |
物理层 | 将0/1转换成物理的传输介质,通过MAC地址进行传输。 |
TCP/IP
协议
TCP/IP协议(Transmission Control Protocol/Internet Protocol),即传输控制协议因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。
TCP/IP
四层结构
分层 | 每层的操作 |
---|---|
应用层 | 提供应用服务。协议:HTTP,FTP,SSH |
传输层 | 让应用程序之间实现通信。协议:TCP,UDP |
网络层 | 该层核心是IP协议,基于IP地址转发数据包。 |
链路层 | 负责接收IP数据包并通过网络发送,或者从网络上接收物理帧,抽出IP数据包,交给网络层 |
OSI模型
与TCP/IP协议
关系
上图列出了OSI与TCP/IP分层之间的大致关系。可以看出,OSI与TCP/IP在分层模块上稍有区别,OSI参考模型注重通信协议必要的功能是什么,而TCP/IP更强调在计算机上实现协议应该开发哪种程序。
OSI参考模型并没有得到普及。TCP/IP协议被广泛应用,今天主角HTTP
属于TCP/IP协议。
HTTP
介绍
HTTP
(HyperText Transfer Protocol, 超文本传输协议)是互联网上应用最为广泛的一种网络协议。HTTP
协议是 TCP/IP
协议模型的子集,属于应用层协议。
客户端与服务端通信流程
HTTP协议和TCP/IP协议族内的其他众多协议相同,用于客户端与服务端之间通信。
请求访问文本或图片资源的一端成为客户端,提供资源响应的一端为服务端。
上图为客户端与服务端交互的流程。客户端发送请求信息,服务端返回响应信息,一来一回完成了一次HTTP通信。
使用Cookie、Session管理状态
HTTP协议是无状态的,它不会记录之前请求的状态。比如,第一次和服务器交互登录成功后,第二次发送请求服务器仍然不知道这是哪个用户。Cookie和Session出现就是为了解决这个问题。
Cookie
第一次和服务器交互登录成功后,服务器会把用户的标识存到Cookie中返回给浏览器。第二次请求,客户端带上Cookie发送给服务端,服务端收到Cookie就知道是哪个用户请求了。
Cookie储存在客户端,不同浏览器对储存大小有不同限制,一般不超过4KB。因此Cookie适合储存少量数据。
Session
Session和Cookie的作用类似,都可以做用户的状态管理。Session储存在服务端,储存的大小和数据形式不受限制。
Cookie和Session两者的区别在本文常见问题小节。
HTTP
报文结构
客户端和服务端之间交互的信息被称为HTTP报文。客户端的HTTP报文叫做请求报文,服务端的叫做响应报文。
HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。
下面两段代码是真实的报文数据,先看一下真实报文,理解报文结构会容易一些。
GET / HTTP/1.1
Host: www.lizhengyang.cn
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: SESSION=t20l97i9pgi9kosj5t9cbil3nm
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 10 Sep 2018 07:19:49 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: blade-2.0.6-BETA
Content-Encoding: gzip
<!DOCTYPE html>
<html>
//此处省略具体HTML数据
</html>
这里的报文数据是抓包拿来的,具体怎样抓取HTTP报文请看另一篇文章:【网络学习笔记】使用Wireshark抓取HTTP报文
请求报文
请求行
请求行包括:请求方法、URI、HTTP协议版本
请求方法
名称 | 描述 | 最低支持协议版本 |
---|---|---|
GET | 请求服务器上的某一资源。 | 1.0 |
POST | 向指定资源提交数据进行处理请求,数据包含在请求体中。 | 1.0 |
HEAD | 用于确认URI的有效性及资源更新的日期时间,不返回报文主体,只返回报文文首部。 | 1.0 |
PUT | 向用来传输文件,将文件内容放进报文主体中,保存到URI指定位置上。 | 1.1 |
DELETE | 与PUT相反,请求URI删除指定资源。 | 1.1 |
OPTIONS | 查询针对请求URI指定的资源支持的方法。 | 1.1 |
TRACE | 用于追踪路径。发送请求时,首部字段Max-Forwards会指定一个数值,每经过一个服务器之后,该数值减1。当该数值为0时,停止传输,最后接收到的服务器响应。 | 1.1 |
CONNECT | 用于在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。 | 1.1 |
GET和POST方法在工作中比较常用。
GET:
- 常用来查询数据
- 请求参数包含在URL里面
- 在浏览器中对请求参数有长度限制
POST:
- 常用来提交数据
- 请求参数在请求体中
- 对参数大小没有长度限制
POST比GET更安全?
- 在浏览器中访问网址发送GET请求,请求参数会附加在网址后面很容被别人看见。POST请求不会把明文参数显示在地址中。从这方面来砍GET比POST安全。
- 如果HTTP请求不配置HTTPS证书,不管是POST请求还是GET请求,所有的参数都会明文在网络上传输,容易被别人查看甚至篡改。从整体来看,不配置安全证书,POST和GET请求都是不安全的。
URI
URI(Uniform Resource Identifier)统一资源标识符,用来标识某一互联网资源名称。URI和URL长得很像,容易混淆,在本文最后常见问题中有两者的差别。
HTTP协议版本
HTTP主要有三个大版本:HTTP/1.0、HTTP/1.1、HTTP/2.0 。在本文最后常见问题中有版本差异的讲解。
请求头
请求头由多个键值对组成,如:
Host: www.lizhengyang.cn
Connection: keep-alive
这些键值被称为首部字段。具体首部字段内容请查看本文HTTP首部字段详解小节
空行
HTTP报文中把第一个出现的空行当做分隔符,空行下面就是报文主体。
请求报文主体
使用POST方法提交的数据必须放在报文主体中,协议没有规定提交的数据使用什么传输格式,实际开发中客户端和服务端可以自己决定传输的格式。
常见的传输格式:
- application/x-www-form-urlencoded
这应该是最常见的POST数据传输格式了。数据格式为“KEY=VALUE”键值对,多组数据中间用“&”符号连接。请求报文如下:
//删减了无关信息
POST http://lizhengyang.cn HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=你好&code=008
注意请求头字段Content-Type
的值为application/x-www-form-urlencoded
-
application/json
传输JSON格式的数据,请求报文如下:
//删减了无关信息 POST http://lizhengyang.cn HTTP/1.1 Content-Type:application/json;charset=utf-8 {"title":"你好","code":80}
注意请求头字段Content-Type
的值为application/json
响应报文
状态行
状态行包括:HTTP协议版本、状态码、状态码描述
状态码类型
类别 | 原因短语 | |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
常见的状态码
状态码 | 描述 |
---|---|
200 OK | 请求成功 |
304 Not Modified | 所请求的资源未修改,服务器不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
403 Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 Not Found | 服务器无法根据客户端的请求找到资源 |
500 Internal Server Error | 服务器内部错误,无法完成请求 |
响应头
格式同请求头。
空行
作用同请求报文中空行。
响应报文主体
常用的传输格式除了请求报文主体中的两种格式外,还有text/html
,HTML网页就是采用的这种格式
HTTP首部字段详解
HTTP首部字段根据实际用途为三种类型:
- 通用首部字段。请求报文和响应报文两方都会使用的首部
- 请求首部字段。从客户端向服务器端发送请求报文时使用的首部。
- 响应首部字段。从服务器端向客户端返回响应报文时使用的首部。
- 实体首部字段。针对请求报文和响应报文的实体部分使用的首部
另外还有一些拓展首部字段,没有在HTTP/1.1
中定义,但使用频率很高。比如:Cookie、Set-Cookie等字段。
通用首部字段
请求首部字段
响应首部字段
实体首部字段
拓展首部字段
- Set-Cookie
用来由服务器端向客户端发送cookie
Set-Cookie: name=zhengyang;Domain=lizhengyang.cn;Path=/;Expires=Mon, 10 Sep 2018 07:19:49 GMT; Secure; HttpOnly
Set-Cookie字段的属性
字段 | 属性 |
---|---|
NAME=VALUE | 赋予 Cookie 的名称和其值(必须项) |
expires=DATE | 指定浏览器可发送 Cookie 的有效期(若不指定则默认为浏览器关闭为止) |
path=PATH | 将服务器上的文件目录作为 Cookie 的适用对象(若不指定则默认为文档所在的文件目录) |
domain=域名 | 作为 Cookie 适用对象的域名(若不指定则默认为创建 Cookie 的服务器的域名) |
Secure | 仅在 HTTPS 安全通信时才会发送 Cookie |
HttpOnly | 加以限制,使 Cookie 不能被 JavaScript 脚本访问。主要目的是为防止跨站脚本攻击对 Cookie 的信息窃取。 |
- Cookie
客户端向服务端发送缓存的Cookie
Cookie:code=0;id=888;
常见问题
uri
与url
的区别?
URI和URL在视觉上两者很相似,在含义上两者同样很相似,经常让人傻傻分不清楚。
概念
- URI(Uniform Resource Identifier)统一资源标识符,用来标识某一互联网资源名称,强调资源的名称。
- URL(Uniform Resource Locator)统一资源定位符,用来从互联网上获得某一个资源,强调资源访问。
理解
北京市 海淀区 中关村 XXX大厦 N层888室 张三
(这是一个虚拟的收件地址)
- URL对应着整个收件地址。通过收件地址能联系到一个人,通过URL能访问一个文件,是一个道理。
- URI对应着收件人姓名张三。在
北京市 海淀区 中关村 XXX大厦 N层888室
大喊张三
就能找到张三本人,但在河北喊破嗓子也找不到北京市的那个张三。
关系
URL是URI的子集,所有的URL都是URI,但不是所有的URI都是URL。
cookie
与session
的区别
对比 | Cookie | Session |
---|---|---|
储存位置 | 储存在客户端 | 储存在服务器 |
安全性 | 不安全 | 安全 |
有效期 | 长 | 短 |
对服务器压力 | 小 | 大 |
HTTP/1.1
、HTTP/2.0
版本特性
在建立 HTTP 标准规范时,制订者主要想把 HTTP 当作传输 HTML文档的协议。随着互联网的发展,web用途更具有多样性,HTTP也广泛应用到移动端,我们对HTTP性能的要求也越来越高。为了适应新时代的要求,HTTP协议逐渐从1.0版本迭代到了1.1、2.0。
HTTP/1.1 特性
缓存处理
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
持久连接
HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
区别用一张图来体现:
增加Host头部字段
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
带宽优化及网络连接的使用
HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
HTTP/2.0 特性
新的二进制格式
HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
多路复用
即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
HTTP/2.0与HTTP/1.1区别
头部压缩
HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
服务端推送
HTTP/2.0之前版本,服务端总是被动的,客户端主动请求才能返回数据。2.0协议,服务端可以主动向客户端发送数据,例如:网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了。