HTTP协议知识总结

540 阅读5分钟

一、第一个问题

http相关一个最经典的问题:浏览器输入URL后HTTP请求返回的完整过程

浏览器输入URL后HTTP请求返回的完整过程
ps:浏览器中的performance会记录整个过程中各个阶段所要花费的时间。

  1. 第一步会做一个redirect(跳转),浏览器可能记录了这个地址以及永久跳转成一个新的地址,所以第一步浏览器先回判断需不需要这个redirect以及跳转到哪里。
  2. 第二部会看缓存(app cache),判断这个页面是不是已经缓存过了,如果有缓存就读取缓存,没有的话就要去服务器请求资源了。
  3. DNS查找(域名解析),去找到这个域名所对应的IP地址。
  4. 创建TCP连接,会涉及三次握手,有可能是HTTPS会跟HTTP有所不同。
  5. request(发送请求)
  6. response(结束相应)

二、HTTP协议基础及发展历史

网络协议分层

经典五层模型

  1. 物理层主要作用是定义物理设备如何传输数据
  2. 数据链路层在通信的实体间建立数据链路连接
  3. 网络层为数据在结点之间传输创建逻辑链路
  4. 传输层
    • 向用户提供可靠的端到端(End-to-End)服务
    • 传输层向高层屏蔽了下层数据通信的细节
  5. 应用层
    • 为应用软件提供了很多服务
    • 构建于TCP协议之上
    • 屏蔽网络传输相关细节

HTTP协议发展历史

  1. HTTP/0.9
    • 只有GET命令
    • 没有HEADER等描述数据的信息
    • 服务器发送相应完毕后,就关闭TCP连接
  2. HTTP/1.0
    • 增加了很多命令
    • 增加status code和header
    • 多字符集支持、多部分发送、权限、缓存等
  3. HTTP/1.1(目前)、HTTPS与HTTP1.1类似
    • 持久连接,通过声明可以保持(不关闭TCP连接)
    • pipeline(同一个连接里发送多个请求)
    • 增加了host(同一个服务器可以跑多个服务)和其他一些命令
    • https 公钥加密,私钥解密,中间人没有私钥
  4. HTTP2
    • 所有数据以二进制传输
    • 同一个连接里面发送多个请求不再需要按照顺序来(并发)
    • 头信息压缩以及推送等提高效率的功能

HTTP的三次握手

TCP连接

三次握手顺序

  • 三次握手的作用:可以避免服务端开启一些无用的连接

HTTPS握手过程

URI、URL、URN

  1. URI
    • 统一资源标示符
    • 用来唯一标识互联网上的信息资源
    • 包括URL和URN
  2. URL
  3. URN
    • 永久统一资源定位符
    • 在资源移动之后还能被找到
    • 目前没有非常成熟的使用方案

HTTP报文

HTTP报文

  1. HTTP方法
    • 用来定义对资源的操作
    • 常用的GET/POST等
    • 从定义上讲有各自的语义
  2. HTTP CODE
    • 定义服务器对请求的处理结果
    • 各个区间的CODE有各自的语义
    • 好的HTTP服务可以通过CODE判断结果

三、HTTP各种特性总览

CORS跨域请求的限制与解决

  1. 需要后端支持:'Access-Control-Allow-Origin':'*'
  2. 预请求:'Access-Control-Allow-Headers':'自定义的头'
  3. 允许的方法:'Access-Control-Allow-Methods':'POST,PUT,DELETE'
  4. 在一定时间内不需要预请求:'Access-Control-Max-Age': '1000' 1000s内不用预请求

http缓存头cache-control

  1. 可缓存性
    • public 都可以进行缓存,下一次可以读缓存不需要再请求
    • private 发起请求的浏览器才可以请求
    • no-cache 任何一个结点都不可以,需要经过服务器的验证
  2. 到期
    • max-age=
    • s-maxage= 代理服务器会读取s-message代替max-age
    • max-stale= 发起端设置的,即便max-age已经过期了,浏览器还是读取这个已经过期的缓存
  3. 重新验证
    • must-revalidate 在设置了max-age的缓存当中,如果已经过期了,必须去原服务端去发送这个请求重新获取数据
    • must-revalidate 用在缓存服务器上的
  4. 其他
    • no-store 永远不能缓存
    • no-transform 不允许随意改变内容
  5. 刷新浏览器缓存通过hash码

资源验证

验证缓存
验证头:验证缓存Last-Modified和Etag的使用

  1. Last-Modified
    • 上次修改时间
    • 配合If-Modified-Since或者If-Unmodified-Since使用
    • 对比上次修改时间以验证资源是否需要更新
  2. Etag
    • 数据签名
    • 配合If-Match或者If-Non-Match使用
    • 对比资源的签名判断是否使用缓存

cookie与session

  1. cookie
    • 通过Set-Cookie设置
    • 下次请求会自动带上
    • 键值对,可以设置多个
  2. cookie属性
    • max-age和expires设置过期时间
    • Secure只在https的时候发送
    • HttpOnly无法通过document.cookie访问(可防止csrf攻击)

HTTP长连接

  1. 一个tcp/ip连接最多允许6个并发请求
  2. Connection: keep-alive持久连接,单个请求完毕后不会关闭tcp/ip连接
  3. http2可以在一个tcp/ip连接上并发请求(串行与并行的区别)

数据协商

  1. 分类
    • 请求
      1. Accept
      2. Content
    • 返回
  2. 请求中通过Accept来进行声明想要什么样的数据
    • Accept 制定的数据类型
    • Accept-Encoding 编码方式,限制压缩方式
    • Accept-Language 语言
    • User-Agent 浏览器相关信息
  3. 服务端返回的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;
  }
}