HTTP请求返回的完整过程
第一章 协议基础及其发展历程
一、经典五层协议
HTTP是在应用层,基于传输层
0x1 低三层
物理层主要作用是定义物理设备如何传输数据
数据链路层在通信的实体间建立数据链路连接
网络层为数据在结点之间传输创建逻辑链路
0x2 传输层
向用户提供可靠的端到端(End-to-End)服务
传输层向高层屏蔽了下层数据通信的细节
0x3 应用层
为应用软件提供了很多服务
构建于TCP协议之上
屏蔽网络传输相关细节
二、HTTP历史
0x1 HTTP/0.9
只有一个命令GET
没有 HEADER等描述数据的信息
服务器发送完毕,就关闭TCP连接
0x2 HTTP/1.0
增加了很多命令
增加 status code和 header
多字符集支持、多部分发送、权限、缓存等
0x3 HTTP/1.1
持久连接
pipeline
增加host和其他一些命令
0x4 HTTP2
HTTP协议原理及实践
HTTP请求返回的完整过程
第一章 协议基础及其发展历程
一、经典五层协议
HTTP是在应用层,基于传输层
0x1 低三层
物理层主要作用是定义物理设备如何传输数据
数据链路层在通信的实体间建立数据链路连接
网络层为数据在结点之间传输创建逻辑链路
0x2 传输层
向用户提供可靠的端到端(End-to-End)服务
传输层向高层屏蔽了下层数据通信的细节
0x3 应用层
为应用软件提供了很多服务
构建于TCP协议之上
屏蔽网络传输相关细节
二、HTTP历史
0x1 HTTP/0.9
只有一个命令GET
没有 HEADER等描述数据的信息
服务器发送完毕,就关闭TCP连接
0x2 HTTP/1.0
增加了很多命令
增加 status code和 header
多字符集支持、多部分发送、权限、缓存等
0x3 HTTP/1.1
持久连接
pipeline
增加host和其他一些命令
0x4 HTTP2
所有数据以二进制传输
同一个连接里面发送多个请求不再需要按照顺序来
头信息压缩以及推送等提高效率的功能
三、HTTP三次握手
0x1 三次握手时序图
防止服务端有无用的开销
抓包三次握手的分析
四、URI/URL/URN
0x1 URI
Uniform Resource Identifier/统一资源标志符
用来唯一标识互联网上的信息资源
包括URL和URN
0x2 URL
Uniform Resource locator/统一资源定位器
http://userpass@host.com80/path?query=string#hash
此类格式的都叫做∪RL,比如ftp协议
0x3 URN
永久统一资源定位符
在资源移动之后还能被找到
目前还没有非常成熟的使用方案
五、HTTP报文
0x1、HTTP方法
用来定义对于资源的操作
常用有GET、POST等
从定义上讲有各自的语义
0x2、HTTP CODE
定义服务器对请求的处理结果
各个区间的CODE有各自的语义
好的HTTP服务可以通过CODE判断结果
六、创建服务
利用Node.js创建一个最简单的服务。
const http = require('http')
http.createServer(function(request,response){
console.log('request come', request.url)
response.end('Hello,HTTP')
}).listen(8888)
第二章 HTTP特性总览
一、HTTP访问控制(CORS)
* 服务端在响应消息头中包含消息头:Access-Control-Allow-Origin,值为服务端允许访问资源的域名称,同时浏览器会根据该值与发起的请求消息头Origin值进行匹配,以确认服务端是否允许访问跨域资源。
* 浏览器在发送非“简单方法”(GET,HEAD请求被定义为简单方法)之前,会发送一个预检请求(通常是一个OPTIONS请求),浏览器根据响应消息头验证服务端是否允许访问跨域资源,从而决定是否需要发送“实际请求”。
* 在服务端根据请求消息头Origin值以决定是否允许浏览器访问跨域资源,返回相应的消息头。
具体来说,在实现时通常需要设置如下几个响应消息头:
1.Access-Control-Allow-Origin:“origin-list” | “null” | “*”,允许访问跨域资源的域名列表,对于预检请求来说,决定是否会发送实际请求。
2.Access-Control-Allow-Credentials:true | false,表明实际请求中是否可以包含用户凭证信息。
3.Access-Control-Allow-Methods:“method”,服务端允许访问的实际请求方法名列表。
4.Access-Control-Allow-Headers:“field-name”,在“实际”请求中可以包含的消息头名称列表。
5.Access-Control-Max-Age:seconds,预检请求结果缓存时间,单位:秒。在该时间范围内,发送实际请求之前不再会发送预检请求。
特别说明:对于需要跨域传递Cookie的场景,必须设置消息头“Access-Control-Allow-Credentials”为“true”,且此时“Access-Control-Allow-Origin”值只能为某一指定单一域名。
简而言之,CORS标准的核心就是:服务端需要在浏览器的跨域请求响应中包含指定消息头。
二、缓存Cache-Control
0x1 客户端对请求的处理(请求头设置的Cache-Control):
0x2 服务器对Cache-Control的配置:
0x3 浏览器对于Cache-Control的响应
三、缓存验证
0x1 缓存运行流程图
0x2 验证头
* Last-Modified
上次修改时间
配合 If-Modified-Since或者If-Unmodified-Since使用
对比上次修改时间以验证资源是否需要更新
* Etag
数据签名
配合If-Match或者If-Non-Match使用
对比资源的签名判断是否使用缓存
四、Cookie和Session
0x1 Cookie
通过Set-Cookie设置
下次请求会自动带上
键值对,可以设置多个
0x2 Cookie属性
Max-age和expires设置过期时间
Secure只在https的时候发送
HttpOnly无法通过document.Cookie访问
四、长链接
HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接。
客户端的长连接不可能无限期的拿着,会有一个超时时间
五、数据协商
- Accept
Accept-Encoding 说明可以接受的内容编码形式(所支持的压缩算法)
Accept-Language 提示用户期望获得的自然语言的优先顺序
User-Agent 首部而可以用来识别发送请求的浏览器。 该字符串中包含有用间隔的产品标记符及注释的清单。 产品标识符由产品名称,后面紧跟的’/’以及产品版本号后成,例如 Firefox/4.0.1
尽管使用该首部来进行内容选择是合理的,但是依赖这个首部来确定用户代理都支持哪些功能特性通常被认为是一个糟糕的做法。
六、Redirect
当服务器找不到资源的时候去跳转到一个新的页面。
302跳转是可控的,301跳转不可控收到用户缓存影响。
if (request.url === '/') {
response.writeHead(302, { // or 301
'Location': '/new'
})
response.end()
}
if (request.url === '/new') {
response.writeHead(200, {
'Content-Type': 'text/html',
})
response.end('<div>this is content</div>')
}
七、内容安全策略 CSP
为了缓解很大一部分潜在的跨站脚本问题,浏览器的扩展程序系统引入了内容安全策略,简单来说,就是我们能够规定,我们的网站只接受我们指定的请求资源。
指令 | 指令和指令值示例 | 指令说明 |
---|---|---|
default-src | ‘self’ cdn.geekmubai.com | 默认加载策略 |
script-src | ‘self’ js.geekmubai.com | 对 JavaScript 的加载策略。 |
style-src | ‘self’ css.geekmubai.com | 对样式的加载策略。 |
img-src | ‘self’ img.geekmubai.com | 对图片的加载策略。 |
connect-src | ‘self’ | 对 Ajax、WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为 400 的响应。 |
font-src | font.cdn.geekmubai.com | 针对 WebFont 的加载策略。 |
object-src | ‘self’ | 针对 、 或 等标签引入的 flash 等插件的加载策略。 |
media-src | media.cdn.geekmubai.com | 针对媒体引入的 HTML 多媒体的加载策略。 |
frame-src | ‘self’ | 针对 frame 的加载策略。 |
report-uri | /report-uri | 告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。 特别的:如果想让浏览器只汇报日志,不阻止任何内容,可以改用 Content-Security-Policy-Report-Only 头。 |