美文网首页HTTP
http通信中的内容协商

http通信中的内容协商

作者: 张柳哥 | 来源:发表于2017-03-03 08:54 被阅读0次

考虑这样的一种情况,服务器对于某个资源有好几个不同的版本,当浏览器发送请求过来的时候,服务器会提供一个最合适的版本给浏览器。

举个例子来说,对于某个网站的主页,服务器可能有“汉语”、“英语”、“法语”,好几个不同的版本,当浏览器发送请求过来的时候,服务器需要判断,到底给浏览器哪个语言的版本比较合适。

服务器为了确定这个比较合适的版本,需要和浏览器进行一些沟通,这个沟通的过程,就是内容协商。

内容协商的过程


那服务器和浏览器是如何进行沟通的呢?目前主流的方法是通过使用请求中一些头部信息来完成这一沟通的,浏览器在发送请求的请求中放置一些头部信息,告诉服务器我需要什么样的数据,然后服务器返回相应版本的数据。

主要使用的请求头有:

1、Accept
2、Accept-Language
3、Accept-Encoding

Accept


accept主要是告诉服务器,浏览器能够接受什么样的数据类型,比如能够接受图片类型的数据,或者能够接受一个xml文件,当然了,浏览器一般可以接受的数据类型是有很多种的,因此一个accept头信息可能是:

accept: text/html, image/jpeg, image/gif, application/pdf

他表示浏览器可以接受htmljpeg图片、pdf三种文件类型,根据这个头部,服务器在发送数据的时候,就要充分考虑浏览器能不能接受。

有的同学可能会问了,如果服务器发送了一份数据,浏览器怎么知道它是什么类型的数据呢?
服务器在给浏览器发送响应数据的时候,也会有头部信息,其中的一个头叫做Content-Type,它会告诉浏览器,我发给你的是什么类型的数据。

那假如对于一份数据,服务器有不同数据类型的版本,即有html类型的,也有jpeg类型的,那么发送哪个版本比较合适呢?
浏览器在accept中可以使用一个叫q的参数,告诉服务器哪些数据类型比较推荐发送。

accept: text/html, image/jpeg; q=0.3, image/gif; q=0.5, application/pdf

如上,浏览器可以接受jpeg、和gif两种类型的图片,但是gif类型的q值是0.5,比较高,q值越高,表示这种数据类型越合适。

那对于text/html并没有制定q值,那这时候表会取q的默认值1,也就是说,text/html等同于text/html; q=1

Accept-Charset


Accept-Charset表示浏览器支持的字符集编码,比如支持utf-8或者gb2312

Accept-Charset: ISO-8859-1,gb2312,utf-8;q=0.7,*;q=0.3

上面表示,浏览器支持ISO-8859-1gb2312utf-8*等字符集,*表示其他任意的字符集,其中的q值表示,浏览器优先支持ISO-8859-1gb2312字符集(默认的q值为1),但是对于utf-8字符集,它的支持权重为0.7,其他字符集的权重为0.3

如果服务器那边有多个字符集版本的资源,那么发送的时候应该优选发送ISO-8859-1gb2312这两个版本,假如服务器那边没有这两个版本那么就推荐发送utf-8版本,实在不行,在发送其他的版本。

Accept-Encoding


在服务器发送数据给浏览器的时候,为了减少数据量,加快发送速度,服务器可以对数据进行压缩,由于服务器给浏览器发送的数据一般是html文本,对于这种文本数据,gzipdeflate这两种压缩算法都有比较好的压缩效果,可以达到原内容的40%。

Accept-Encoding头就是用于浏览器告诉服务器,我希望你发送的数据是压缩过的,并且使用的压缩算法是我指定的:

Accept-Encoding: gzip; q=0.9, deflate; q=0.7

上面表示,浏览器支持gzipdeflate两种压缩算法,但是推荐服务器使用gzip来压缩,因为它的q值比较高,如果服务器发送过来的数据用的压缩算法浏览器不支持,那么就会出错。

还有一个问题是,浏览器怎么知道服务器用了何种压缩算法呢?
同样,服务器发送的响应中,有一个对应的头部:Content-Encoding,会告诉浏览器,使用了什么样的压缩算法。

Accept-Language


如果一个网站支持多语言,一般会用到这个头信息,Accept-Language主要是告诉服务器,当前用户比较擅长某种语言(中文、英文等),建议服务器发送这种语言的页面过来:

Accept-Language: zh-CN,fr-FR;q=0.5

zh-CN表示中文,fr-FR表示法语,上面表示,浏览器希望服务器发送zh-CN中文版本的页面,因为它的q值是1,如果没有中文的,那就发送法语版本的。

那浏览器根据什么来判断,什么语言比较合适用户呢?

浏览器一般会根据用户的操作系统(比如中国一般用的是中文版的操作系统)来给予语言方面的建议,有的浏览器本身就有各种语言的版本,也可以根据自己的版本信息来进行判断。

Vary


在网络当中,浏览器和服务器并不是直接进行通信的,在他们中间往往有很多的代理服务器:

浏览器=>代理服务器1=>代理服务器2=>...=>服务器

其中的代理服务器一般具有缓存的功能,现在假设,一个浏览器发送了请求,要求服务器提供压缩版本的数据,这个数据返回后,会被缓存在代理服务器中,然后,另外一个浏览器发送了请求同样数据的请求,但是不是压缩版本的,这个时候就容易发生问题。

当第二个请求到达代理服务器的时候,代理服务器发现请求的资源已经缓存起来了,就会把的压缩版本资源返回,这样就会导致错误。

Vary头是服务器返回响应的时候,放置在响应头当中的,用来告诉这些代理服务器,当你缓存我的时候,需要补上对应的请求中的一些头信息作为我的版本信息,这样下个请求过来的时候,除了判断是不是相同的url,还需要判断版本信息是不是一样的,最后来决定是不是使用缓存:

Vary: Accept-Encoding, Accept

上面的头信息是告诉代理服务器,缓存我(响应)的时候,你需要加上对应请求当中的Accept-EncodingAccept信息,这样,如果下个请求当中的Accept-EncodingAccept信息和缓存中的不一致,就会认为缓存不可用。

为什么代理服务器在检测版本的时候,不使用响应头Content-*头呢?
原因是有些代理服务器会自动忽略掉响应当中的一些头,比如响应中的Content-Encoding头,这样代理服务器就根本不知道这个响应数据是不是经过压缩的了。

参考链接:


相关文章

  • http通信中的内容协商

    考虑这样的一种情况,服务器对于某个资源有好几个不同的版本,当浏览器发送请求过来的时候,服务器会提供一个最合适的版本...

  • Content negotiation - Django RES

    内容协商-Django REST框架 negotiation.py 内容协商 http有关于“内容协商”的几种机制...

  • http内容协商机制

    指客户端和服务器之间就响应资源内容进行交涉,然后提供给客户端最为合适的资源,内容协商会以响应资源的语言、字符集、编...

  • Tornado异步笔记(三)--- 持久连接 KeepAlive

    HTTP 持久连接 HTTP通信中,client和server一问一答的方式。HTTP是基于TCP的应用层协议,通...

  • 3.6 内容协商

    当浏览器的默认语言为英语或中文,访问相同的URI的web页面时,则会显示对应的英文版或者中文版的web页面。这样的...

  • HTTP的协商缓存策略

    http缓存策略 - 协商缓存(对比缓存) 服务器端缓存策略(即判断是否可以缓存)服务端判断一个资源是否被缓存服务...

  • 浏览器缓存原理

    背景:http1中利用缓存机制可以节约http请求数量,减少请求数据 弱缓存(协商缓存) 1.第一次请求,服务端通...

  • 内容协商与编码

    内容协商技术 共有3种不同的方法可以决定服务器上哪个页面最适合客户端:让客户端来选择,服务器自动判定,或中间代理来...

  • [Django Rest framework文档翻译]-Resp

    REST framework是通过提供一个Response类来支持HTTP的内容协商能力的。这个类允许你根据不同的...

  • 【前端 · 面试 】HTTP 总结(九)—— HTTP 协商缓存

    最近我在做前端面试题总结系列,感兴趣的朋友可以添加关注,欢迎指正、交流。争取每个知识点能够多总结一些,至少要做到在...

网友评论

    本文标题:http通信中的内容协商

    本文链接:https://www.haomeiwen.com/subject/wowgwttx.html