HTTP原理
常见的http场景
- url到网页展示
- ajax获取数据
- img标签加载图片
五层网络模型
- 应用层:
- 作用:为应用软件提供了更多的服务(
http服务
),构建于tcp协议之上(网络传输优化
),屏蔽了网络传输相关细节。
- 作用:为应用软件提供了更多的服务(
- 传输层:
- 分类:
TCP|UDP
- 作用:向用户提供了可靠的端到端的服务,向高层屏蔽了下层数据通信的细节。
- 分类:
- 网络层:
- 作用:在节点之间传输创建逻辑链路。
- 数据链路层:
- 作用:在通信的实体间建立数据链路链接。
- 物理层:
- 作用:定义物理设备如何传输数据

http协议发展史
tcp的三次握手
- 本质:http request 是建立在 TCP connection 之上的,建立
TCP connection
需要进行三次🤝 - 三次🤝的意义:当服务器端向客户端传输数据包出现丢失的使用,确保客户端正常收到了数据,
避免服务器端开启无用的服务
。

URI URL URN
- URI:统一资源标志符,用来唯一标识互联网上的信息资源,它包括了URL和URN。
- URN:永久统一资源定位符。
- URL:统一资源定位器
[schema+host+port+path+serach]
。 - schema:定义请求的发送方如何发送数据,和请求的接收方如何解析数据;约束传输数据的格式。
- host:物理服务器主机的地址。
- port:定位物理服务器上运行的web服务器。
- path:路由对应到web服务结构下到路径。
- serach:通过url传递给服务器到参数
http报文格式
- 请求报文格式
格式 | 内容 |
---|---|
首行 | 请求方法 路由 http协议版本 |
首部 | Accept:text/* |
- 响应报文格式
格式 | 内容 |
---|---|
首行 | http协议版本 状态码 状态信息 |
首部 | Content-type:text/plain Cache-control:max-age=2000 |
主体 | i'm a message |
跨域资源共享(cors)
-
定义:CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应.
-
跨域是发生在浏览器端[请求已经发送到了服务器,服务器也做出了响应]
sequenceDiagram
浏览器端-->>服务器端: 发送一个跨域的请求
服务器端-->>浏览器端: 服务器收到请求,并返回响应的结果
- 如何设置允许发生跨域请求,更多地址。
// 设置允许跨域
reponse.writeHead(200, {
// script img link 标签是允许跨域的
// * 表示所有的域名都可以访问到指定的域名
"access-control-allow-origin": *
"access-control-allow-header": "设置允许的请求头"
"access-control-allow-methods": "设置允许的请求方法"
"access-control-max-age":"设置在指定时间里,浏览器不需要发送预请求进行验证"
})
- cors的预请求:浏览器得到服务器允许访问请求资源的一种方式。
// 当发生跨域的时候,浏览器默认只允许GET|HEAD|POST请求,其他方法浏览器都会有预请求验证的
// 允许的content-type, text/plain | multipart/form-data|application/x-www-form-urlencoded
// 请求头限制:Accept|Accept-Language|Content-Language|Content-Type|DPR|Downlink|Save-Data|Viewport-Width|Width
缓存 Cache-Control(客户端缓存)
强缓存
- 问题:当静态资源发送变化的时候,客户端无法感知到服务器端的静态资源发生了变化,浏览器端还是会使用缓存。导致请求之前的资源。[
前端使用hash进行刷新缓存
]
协商缓存
chrome中的 disable-cache
服务器端如何做etag
缓存
- 可缓存性:
- public:资源可以被浏览器缓存,也可以被代理服务器缓存
- private:资源只能被浏览器缓存
- no-cache(协商缓存):本地可以有缓存,但是
每次请求都必须向服务器请求认证缓存的可用性
, 确定是否使用浏览器缓存。 - 缓存时间设置:
- max-age: Cache-Control: max-age=
- s-maxage: 在代理服务器端,优先级大于max-age
- max-stale:
- 重新验证:
- must-revalidate
- proxy-revalidate
- 限制缓存
- no-cache:本地可以有缓存,但是
每次请求都必须向服务器请求认证缓存的可用性
, 确定是否使用浏览器缓存。 - no-store:不使用缓存
- no-transform:约束代理服务器端,不能更改资源.
- 缓存验证:
- Last-Modified(
if-Modified-Since
):记录上次资源修改的时间 - ETag(
if-Non-Match
):一个资源对应一个唯一的签名
// 设置max-age
reponse.writeHead(200, {
"Cache-Control": 'max-age = 2000,public',
"Content-Type": "text/javascript",
"Last-Modified": "123",
"Etag": "777"
})
const eTag = request.header['if-none-match'];
if (eTag === '777') {
// 304 重定向
reponse.writeHead(304, {
"Cache-Control": 'max-age = 2000,public',
"Content-Type": "text/javascript",
"Last-Modified": "123",
"Etag": "777"
})
response.end('')
} else {
reponse.writeHead(200, {
"Cache-Control": 'max-age = 2000,public',
"Content-Type": "text/javascript",
"Last-Modified": "123",
"Etag": "777"
})
response.end('asd')
}
cookie[Set-Cookie
]和session
- 作用:在同域名下进行资源访问,浏览器 所有请求会自动带上cookie[
可能存在多余性能问题:通常通过将不需要cookie认证的静态资源和需要认证的接口放在不同的域名下面
],request头中的Cookie字段。 - 设置cookie
// 服务器端通过设置 Set-Cookie,设置给浏览的值。
// 时期:max-age和expires设置过期时间,或者关闭浏览器
// Secure只在https的时候发送
// 设置HttpOnly 无法通过document.cookie访问
// 同一个主域名下的所有二级域名都可以访问到cookie
res.writeHead(200, {
// 数组设置多个cookie:响应头中将出现两个Set-Cookie字段
// 单个键值对:设置单个cookie
// max-age:设置cookie的过期时间
// HttpOnly:被设置的cookie无法通过document.cookie访问。
// domain:cookie不能进行跨域设置
"Set-Cookie": ["key=value;max-age=2", "key1=value1;HttpOnly", "key2=value2;domain=test.com"]
})
http长连接[Connection
]
- 定义:http的请求是基于tcp发送的,tcp的连接分为长连接和短连接
// Response Header
// Chrome最多允许6个并发的tcp连接。
// Connection
res.writeHead(200, {
"Connection": "close",//关闭调长链接,每次请求都会走三次握手重新建立tcp连接
"Connection": "keep-alive"(默认值)
})
// http2中 允许一个tcp连接并发多个http请求(信导复用)
数据协商[Accept
]
- 定义:请求端通过发送不同的头信息,来约束服务端返回数据的格式
- 请求头:
Accept: 申明想要请求数据的类型
Accept-Encoding: 请求的编码格式, 通常用来约束服务端使用什么压缩算法
Accept-Language: zh-CN, zh;q = 0.9(q表示权重)
User-agent: 浏览器的相关信息
Content-Type: 客户端会根据Content-Type, 输出不同的payload格式
- 响应头:
Content-Type: 服务端返回的数据格式
X-Content-Type-Options: "nosniff"
Content-Encoding: 告诉客户端服务端使用的是什么压缩算法
Content-Language:
- node中开启gzip
const zlib = require('zlib');
重定向[redirect]
- 状态码:3xx,浏览器端根据状态码,来决定自身的行为
- 302 临时重定向:需要服务器端的一次location,重新定向到新的地址
- 301 永久重定向:浏览器直接使用缓存
if (request.url === '/') {
response.writeHead(302, {
'Location': '/new' // 同域的情况下 可以不写协议和域名
})
}
if (request.url === '/new') {
response.writeHead(200, {
'Content-Type': 'text/html'
})
response.end('<div>this is content</div>')
}
CSP(content-security-policy)
-
作用:限制资源获取,报告资源获取越权.
-
主要目标:CSP 的主要目标是
减少和报告 XSS 攻击
,XSS 攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。 -
限制方式:例如 default-src限制全局
response.writeHead(200, {
'Content-Security-Policy': 'default-src http: https:'
})
//只能加载同域下的外链js脚本
response.writeHead(200, {
'Content-Security-Policy': 'default-src \'self'\
'
})
//向服务器报告
response.writeHead(200, {
'Content-Security-Policy': 'default-src \'self'\;report / server 'address '
})
// meta标签实现
<meta http-equiv = 'Content-Security-Policy'
content = 'default-src http: https' >