http网络协议小结

  1. 网络传输五层模型

    应用层(HTTP,FTP) —> 传输层(TCP,UDP)—> 网络层(IP协议)—-> 数据链路层 —-> 物理层

    • 物理层:物理设备间传输数据
    • 数据链路层:在通信的实体间建立连接
    • 网络层:寻找地址
  1. HTTP协议的发展

    • HTTP/0.9:只有GET请求,没有头部信息,服务器发送完就关闭tcp连接
    • HTTP/1.0:增加很多命令,增加status code和头部信息,以及支持缓存等
    • HTTP/1.1:支持持久连接,增加host(在一台服务器跑多个服务)
    • HTTP/2:所有数据都以二进制传输,头部压缩及推送功能
  2. HTTP三次握手

    seq是数据包本身的序列号;ack是期望对方继续发送的那个数据包的序列号(ack表示对接收到的数据包表示确认), seq和ack是对应的

    1
    2
    3
    4
    5
    ##客户端及服务器端发送http请求和响应需要创建 tcp连接来创建传输的管道
    ##在HTTP/1.1中,可以在一个tcp连接里面发送多个请求,即持久连接
    client:SYN
    server:SYN,ACK
    client:ACK

  3. HTTP4次挥手

    1
    2
    3
    4
    5
    client:发送FIN标志位表示断开,以及seq=p
    server:发送ACK,ack=p+1表示回应
    ---server处理完自己的事情,比如还没发送完数据
    server:发送FIN标志,ACK以及seq=q
    client:返回ACK,ack=q+1

  4. CORS跨域

    • 同源政策:协议相同,域名相同,端口相同

      可以在服务器端设置响应头部信息:Access-Control-Allow-Origin

    注: 无论设置与否,其实浏览器已经接收到返回的内容了,只是浏览器没有检测到这个响应头部,所以做出了限制,并报错。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #node.js
    const http = require('http')
    http.createServer((req,res) => {
    res.writeHead(200, {
    'Access-Control-Allow-Origin': 'http://google.com' //这里过滤条件为google域名
    })
    })
    //只能写一个这样的头部,设置多个域名可以用函数来实现(express.js)
    app.all('*', function(req, res, next) {
    if( req.headers.origin == 'https://www.google.com' || req.headers.origin == 'https://www.baidu.com' ){
    res.header("Access-Control-Allow-Origin", req.headers.origin);
    res.header('Access-Control-Allow-Methods', 'POST, GET');
    res.header('Access-Control-Allow-Headers', 'X-Requested-With');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    }
    next();
    });
  5. CORS预请求:相当于发送一个OPTIONS请求到服务器端验证

    CORS默认只支持GET,POST,和HEAD方法

    CORS默认允许的Content-Type:

    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

    CORS遇到非默认允许的请求头也需要预请求的操作

    1
    2
    3
    4
    5
    设置预请求:
    1. 'Access-Control-Allow-Headers':'xxx' //设置了之后请求的时候设定的头部才会被允许
    #实际上先用OPTIONS请求,去获得服务器端的一个认可,然后再去实际请求。所以发送了两个请求
    2. 'Access-Control-Allow-Methods':'POST,PUT,DELETE'
    3. 'Access-Control-Max-Age':'1000' //表示1000秒内不需要发送预请求来验证
  6. 缓存头Cache-Control

    1
    'Catch-Control':'max-age=20000,no-cache' //用逗号分隔
    • piblic:都可以进行缓存的操作

    • private:只有发起请求的浏览器可以缓存

    • no-cache:可以在本地进行缓存,但是要发送请求到服务器端去验证,是否可以使用,才可以使用

    • no-store:死活不可以缓存,永远拿新的


    • 到期时间

      • max-age = seconds :到期时间,最多缓存时间(浏览器专用)
      • s-maxage=seconds:代理服务器专用
    • 重新验证

      • must-revalidate:过了max-age之后,必须到源服务器端去请求,不能读取缓存

      • proxy-revalidete:代理服务器在过期后,也必须重新去新请求

        no-transform:不能对资源进行转换

1
2
合理的前端缓存方法:
设置打包完成的js文件名称是 js内容的哈希码,只要内容不变,就从缓存中读取;如果内容有变化,hash码就变化,那么文件名对应的请求url路径变化,就相当于请求了新的资源。
  1. 在Cache-Control头部设置了no-cache之后,需要资源验证

    验证头:Last-Modified & Etag

    • Last-Modified:上次修改时间

      配合请求头中的If-Modified-Since使用,服务器端收到这个请求头后,去对比文件的上次修改时间,如果一致,说明没有修改。返回304通知浏览器使用缓存

    • Etag:数据签名(对资源的内容生成唯一的签名,标记这个资源)

      浏览器请求时会带上If-Match或者If-Non-Match请求头,值就是服务器端返回过来的Etag值,然后对比资源签名判断是否使用缓存,如果缓存就返回304状态码(304的意思not modified,没有修改)

    1. cookie:键值对

      服务器端生成,通过Set-Cookie响应头来设置。客户端下次就会自动带上Cookie请求头

      属性:

      • max-age(设置时间多长)和expires(到哪个时间点过期)设置过期时间
      • Secure:只在https的时候发送
      • HttpOnly:无法通过document.cookie来访问
      • domain=xxx.com:xxx.com下的所有二级域名可以共享cookie
      1
      2
      3
      #node.js
      'Set-Cookie':['id=123; max-age=20', 'abc=456;domain=test.com'] //通过数组设置多个cookie值
      //abc=456这个cookie值在a.test.com或者其他二级域名b.test.com都可以访问到
    2. HTTP长连接:复用tcp的连接

      google调试工具network中有一个connection id,是tcp连接的id,可以看到是不是同一个tcp连接。

      google浏览器默认可以并发6个tcp连接。当第7个请求发送时,要等前面6个有一个空出来才会去在这个tcp连接上通讯。

      保持长连接:设置'Connection':'keep-alive'

      服务器端也可以设置'Connection':'close' :表示一个tcp请求完成之后,就关闭掉。所以所有的请求都会创建一个新的tcp连接,google调试工具中的connection id都是不同的,开销很大。

    3. 数据协商

      请求:Accept头部

      • Accept:数据类型
      • Accept-Encoding:gzip,deflate,br什么编码方式来传输。用来限制服务端对数据的压缩方式
      • Accept-Language:zh-CN,zh;q=0.9 , en;q=0.8要求返回的信息语言、 q代表权重
      • User-Agent:用判断返回pc端的页面还是移动端的页面

      返回:Content头部

      • Content-Type:对应请求的Accept
      • Content-Encoding:用了什么数据压缩方式
      • Content-Language
      1
      2
      3
      4
      5
      6
      7
      数据类型格式:type/subtype 主类型/分类型
      image/png
      image/jpeg
      text/plain 显示源码
      text/html 显示html解析后的
      application/json
      application/javascript
    4. Redirect重定向,在服务器端设置Location头,并返回302(临时重定向)或者301(永久重定向,除非用户自动清除浏览器,否则浏览器总是去跳转请求新的地址,不会去请求旧地址)

      1
      'Location':'/xxx'
    5. CSP(Content-Security-Policy):内容安全政策

      • 限制资源获取
        • defalut-src:限制全局所有和连接请求有关的
        • 定制:connect-src 、 img-src 、 script-src等
      • 报告获取资源越权
      1
      2
      3
      'Content-Security-Policy':'default-src http: https:' //只能通过http或者https的方式进行加载,网页里面嵌套js无法执行
      ------------
      作用就是限制外链
    6. Nginx代理:待了解

    7. HTTPS:私钥&公钥