一、第一个问题
http相关一个最经典的问题:浏览器输入URL后HTTP请求返回的完整过程
ps:浏览器中的performance会记录整个过程中各个阶段所要花费的时间。- 第一步会做一个redirect(跳转),浏览器可能记录了这个地址以及永久跳转成一个新的地址,所以第一步浏览器先回判断需不需要这个redirect以及跳转到哪里。
- 第二部会看缓存(app cache),判断这个页面是不是已经缓存过了,如果有缓存就读取缓存,没有的话就要去服务器请求资源了。
- DNS查找(域名解析),去找到这个域名所对应的IP地址。
- 创建TCP连接,会涉及三次握手,有可能是HTTPS会跟HTTP有所不同。
- request(发送请求)
- response(结束相应)
二、HTTP协议基础及发展历史
网络协议分层
- 物理层主要作用是定义物理设备如何传输数据
- 数据链路层在通信的实体间建立数据链路连接
- 网络层为数据在结点之间传输创建逻辑链路
- 传输层
- 向用户提供可靠的端到端(End-to-End)服务
- 传输层向高层屏蔽了下层数据通信的细节
- 应用层
- 为应用软件提供了很多服务
- 构建于TCP协议之上
- 屏蔽网络传输相关细节
HTTP协议发展历史
- HTTP/0.9
- 只有GET命令
- 没有HEADER等描述数据的信息
- 服务器发送相应完毕后,就关闭TCP连接
- HTTP/1.0
- 增加了很多命令
- 增加status code和header
- 多字符集支持、多部分发送、权限、缓存等
- HTTP/1.1(目前)、HTTPS与HTTP1.1类似
- 持久连接,通过声明可以保持(不关闭TCP连接)
- pipeline(同一个连接里发送多个请求)
- 增加了host(同一个服务器可以跑多个服务)和其他一些命令
- https 公钥加密,私钥解密,中间人没有私钥
- HTTP2
- 所有数据以二进制传输
- 同一个连接里面发送多个请求不再需要按照顺序来(并发)
- 头信息压缩以及推送等提高效率的功能
HTTP的三次握手
- 三次握手的作用:可以避免服务端开启一些无用的连接
HTTPS握手过程
URI、URL、URN
- URI
- 统一资源标示符
- 用来唯一标识互联网上的信息资源
- 包括URL和URN
- URL
- 统一资源定位器
- user:pass@host.com:80/path?query=…
- 此类格式的都叫做URL,比如ftp协议
- URN
- 永久统一资源定位符
- 在资源移动之后还能被找到
- 目前没有非常成熟的使用方案
HTTP报文
- HTTP方法
- 用来定义对资源的操作
- 常用的GET/POST等
- 从定义上讲有各自的语义
- HTTP CODE
- 定义服务器对请求的处理结果
- 各个区间的CODE有各自的语义
- 好的HTTP服务可以通过CODE判断结果
三、HTTP各种特性总览
CORS跨域请求的限制与解决
- 需要后端支持:'Access-Control-Allow-Origin':'*'
- 预请求:'Access-Control-Allow-Headers':'自定义的头'
- 允许的方法:'Access-Control-Allow-Methods':'POST,PUT,DELETE'
- 在一定时间内不需要预请求:'Access-Control-Max-Age': '1000' 1000s内不用预请求
http缓存头cache-control
- 可缓存性
- public 都可以进行缓存,下一次可以读缓存不需要再请求
- private 发起请求的浏览器才可以请求
- no-cache 任何一个结点都不可以,需要经过服务器的验证
- 到期
- max-age=
- s-maxage= 代理服务器会读取s-message代替max-age
- max-stale= 发起端设置的,即便max-age已经过期了,浏览器还是读取这个已经过期的缓存
- 重新验证
- must-revalidate 在设置了max-age的缓存当中,如果已经过期了,必须去原服务端去发送这个请求重新获取数据
- must-revalidate 用在缓存服务器上的
- 其他
- no-store 永远不能缓存
- no-transform 不允许随意改变内容
- 刷新浏览器缓存通过hash码
资源验证
验证头:验证缓存Last-Modified和Etag的使用- Last-Modified
- 上次修改时间
- 配合If-Modified-Since或者If-Unmodified-Since使用
- 对比上次修改时间以验证资源是否需要更新
- Etag
- 数据签名
- 配合If-Match或者If-Non-Match使用
- 对比资源的签名判断是否使用缓存
cookie与session
- cookie
- 通过Set-Cookie设置
- 下次请求会自动带上
- 键值对,可以设置多个
- cookie属性
- max-age和expires设置过期时间
- Secure只在https的时候发送
- HttpOnly无法通过document.cookie访问(可防止csrf攻击)
HTTP长连接
- 一个tcp/ip连接最多允许6个并发请求
- Connection: keep-alive持久连接,单个请求完毕后不会关闭tcp/ip连接
- http2可以在一个tcp/ip连接上并发请求(串行与并行的区别)
数据协商
- 分类
- 请求
- Accept
- Content
- 返回
- 请求
- 请求中通过Accept来进行声明想要什么样的数据
- Accept 制定的数据类型
- Accept-Encoding 编码方式,限制压缩方式
- Accept-Language 语言
- User-Agent 浏览器相关信息
- 服务端返回的content
- Content-Type
- Content-Encoding
- Content-Language
Redirect
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>')
}
一个简单的https的nginx配置
proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m; #nginx代理缓存
server {
listen 80;
# listen [::]:80 default_server;
server_name test.com;
# return 302 https://$server_name$request_uri;
location / {
proxy_cache my_cache;
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
}
}
server {
listen 443 http2; # http2
server_name test.com;
# http2_push_preload on; # http2
ssl on;
ssl_certificate_key ../certs/localhost-privkey.pem;
ssl_certificate ../certs/localhost-cert.pem;
location / {
proxy_cache my_cache;
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
}
}