• http 内容协商


    http 内容协商

    在 HTTP 协议中,内容协商是一种机制,通过为同一 URI 指向的资源提供不同的展现形式,可以使用户代理选择与用户需求相适应的最佳匹配(例如,文档使用的自然语言,图片的格式,或者内容编码形式)。

    当一个资源被访问时,特定的展现方式通过客户端和服务端之间的协商方式来选取的,最佳的展现方式可以通过两种机制来实现:

    • 客户端通过设置Accept头部传递给服务端,服务端返回对应形式的资源(又称为服务端驱动型内容协商机制或者主动协商机制)。
    • 客户端没有设置Accept,服务端返回300或者406状态码(又称为代理驱动型协商机制或者响应式协商机制,这种方式一般用作备选方案)

    服务端驱动型内容协商机制(主动协商机制)

    HTTP/1.1 规范指定了一系列的标准消息头用于启动服务端驱动型内容协商(Accept、Accept-Charset、 Accept-Encoding、Accept-Language)。服务器会使用 Vary 消息头来说明实际上哪些消息头被用作内容协商的参考依据。

    Accept

    Accept 首部列举了用户代理希望接收的媒体资源的 MIME 类型。其中不同的 MIME 类型之间用逗号分隔,同时每一种 MIME 类型会配有一个品质因数(quality factor),该参数明确了不同 MIME 类型之间的相对优先级。

    Accept的值可以通过开发者手动设置或者浏览器自动设置。如果开发者没有设置Accept值,那么浏览器会设置默认值。

    Accept-Charset

    Accept-Charset首部用于告知服务器该客户代理可以理解何种形式的字符编码。由于UTF-8编码被广泛支持,成为首选的字符编码类型,大多数浏览器已经将 Accept-Charset 首部移除,不在发送该字段(即使开发者设置了)。

    Accept-Encoding

    用于告知服务器该客户代理接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法。

    将 HTTP 消息进行压缩是一种最重要的提升 Web 站点性能的方法。该方法会减小所要传输的数据量的大小,节省可用带宽。浏览器总是会发送该首部,服务器则应该配置为接受它,并且采用一定的压缩方案。开发者不能手动设置,会报错,浏览器会默认设置(gzip, deflate, br)

    Accept-Language

    用于告知服务器该客户代理接收的语言。

    Vary

    Vary 是由服务器在响应中发送的,用于告知服务器使用了请求中哪些主动协商相关的字段。这个首部是必要的,它可以用来通知缓存服务器决策的依据,这样它可以进行复现,使得缓存服务器在预防将错误内容提供给用户方面发挥作用。

    缓存服务器为了能够与服务端驱动型内容协商机制协同工作,需要知道服务器选择传送内容的决策依据。这样的话,缓存服务器就可以重复该算法,直接提供恰当的内容,而不需要向服务器发送更多的请求。显然,通配符 ‘*’ 阻碍了缓存机制发挥作用,因为缓存服务器并不知道该通配符究竟指代哪些元素。

    代理驱动型内容协商机制

    服务端驱动型内容协商机制由于一些缺点而为人诟病——它在规模化方面存在问题。在协商机制中,每一个特性需要对应一个首部。如果想要使用屏幕大小、分辨率或者其他方面的特性,就需要创建一个新的首部。而且在每一次请求中都必须发送这些首部。在首部很少的时候,这并不是问题,但是随着数量的增多,消息体的体积会导致性能的下降。带有精确信息的首部发送的越多,信息熵就会越大,也就准许了更多 HTTP 指纹识别行为,以及与此相关的隐私问题的发生。

    从 HTTP 协议制定之初,该协议就准许另外一种协商机制:代理驱动型内容协商机制,或称为响应式协商机制。在这种协商机制中,当面临不明确的请求时,服务器会返回一个页面,其中包含了可供选择的资源的链接,资源呈现给用户,由用户做出选择(状态码 300 Multiple Choices)。这种方案有不少问题,首先多一次网络往返;其次服务端同一文档的某些版本可能是为拥有某些技术特征的客户端准备的,而普通用户不一定了解这些细节。举个例子,服务端通常可以将静态资源输出为压缩和未压缩两个版本,压缩版显然是为支持压缩的客户端而准备的,但如果让普通用户选,很可能选择错误的版本。最后是HTTP 标准没有明确指定提供可选资源链接的页面的格式。

    除了退回至服务端驱动型内容协商机制外,这种自动化方法几乎无一例外都是通过脚本技术来完成的,尤其是 js 重定向技术:在检测了协商的条件之后,脚本会触发重定向动作。

    比如说服务端返回多个链接提供用户选择

    res.end(
      JSON.stringify({
        data: {
          image: "/imageResource",
          file: "fileResource",
        },
      })
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    前端在获取后数据根据需要的类型使用window.location.replace或者window.location.href来实现重定向。

    // 类似 HTTP 重定向, 不能通过浏览器中的前进后退按钮来返回上一个url
    window.location.replace(data.image);
    
    // 类似点击 a 标签的链接
    window.location.href = data.file;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    不过这种方式需要额外发送一次请求,会减慢了将资源呈现给用户的速度。

    以上的协商内容只是客户端和服务端的消息互通,如果客户端没有响应的逻辑处理,那么设置的任何东西其实都是没有作用的

    扩展

    MIME TYPE

    MIME( Multipurpose Internet Mail Extensions 多功能网络邮件扩充协议)是一种标准,用来表示文档、文件或字节流的性质和格式。

    它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。

    访问一个网页,获得一个资源后,浏览器通过媒体资源类型 MIME Type,媒体资源类型通过 http 协议,由 web 服务器通过Content-Type 来告知浏览器如何解析。

    字符集与字符编码

    字符集(Charset)

    是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。

    字符编码(Character Encoding)

    是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项*本技术。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用元件(硬件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。

  • 相关阅读:
    ThreadLocal(4):ThreadLocal的核心方法源码
    Nginx之QPS限制模块解读
    JavaScript:模拟拍照
    一篇文章讲清楚!数据库和数据仓库到底有什么区别和联系?
    【最优化理论】人工智能与最优化理论的联系
    shell练习
    Web3:数字身份与隐私保护的新篇章
    excel、word、ppt 下载安装步骤整理
    【卖出备兑看涨期权策略(Covered_call)】
    计算机网络-网络层(路由算法与路由协议概述,IP数据报格式,IP数据报分片)
  • 原文地址:https://blog.csdn.net/qq_42880714/article/details/128088889