• Accept 表示请求方希望的资源类型,或者能解析识别的类型
  • Content-Type 表示实际发送的资源类型

这里资源类型通过 MIME types 表示。

Accept

Accept 是浏览器发送的请求头,用于表示想要的资源类型。根据请求的上下文不同,所设置的 Accept 请求头会相应变化。服务器根据 content negotiation 规则选择最合适的类型设置 Content-Type 并返回。

例如请求路由页面时,Chrome 设置 Accept 为

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

对于页面中的样式文件 css,其 Accept 为:

Accept: text/css,*/*;q=0.1

可用的值有以下几种:

  • <MIME_type>/<MIME_subtype>,精确指定,示例: text/html
  • <MIME_type>/*, 不限制子类型,比如 image/* 会匹配 image/pngimage/svgimage/gif 以及其他任何图片类型。
  • */* 任意 MIME 类型。
  • ;q= (q-factor weighting) 多种类型组合的情况,通过指定权重(quality value)来表明每种类型的优先级。

Quality value

Header 中逗号分隔的值,每项的权重,或优先级。

比如:

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

表示:

优先级
text/htmlapplication/xhtml+xml 1.0
application/xml 0.9
*/* 0.8

Content-Type

用来表示资源的类型。某些情况下,浏览器会对资源的类型进行嗅探而忽略掉服务器返回的 Content-Type。如果想强制客户端使用服务器返回的类型,可加上 X-Content-Type-Options:nosniff 响应头。

支持的值有:

  • media-type,常见的 Content-Type 可 参考这里
  • charset,指定资源编码类型。
  • boundary, 多个资源实例情况下,指定资源的分界符。比如 form 表单提交时分隔多个表单字段,见后面示例。

一般情况下,包含在由服务器发送给客户端的响应头里。但也存在浏览器发送给服务器的情况,比如 POST 请求,表单提交这种由浏览器向服务器发送数据的情况下。

表单的提交类型

form 表单中,提交的内容类型通过表单的 enctype 属性来指定。包含两种:

  • application/x-www-form-urlencoded 较古老的格式,只支持简单文本,不支持文件上传。
  • multipart/form-data 较新,支持文件上传,尺寸较大的二进制数据等。

一个表单提交示例

通过 koa.js 搭建一个简单的表单提交示例,以查看 Content-Type。

server.js

const { createReadStream } = require("fs");
const Koa = require("koa");
const app = new Koa();
const router = require("koa-router")();
const koaBody = require("koa-body"); router

.get("/", async ctx => {

ctx.type = "html";

ctx.body = createReadStream("form.html");

})

.post(

"/submit",

koaBody({

multipart: true

}),

ctx => {

console.log("form data is:", ctx.request.body);

ctx.body = JSON.stringify(ctx.request.body);

}

); app.use(router.routes()); app.listen(3000); console.log(</span>server started at http://localhost:3000<span class="pl-pds">);

form.html

<form action="/submit" method="POST" enctype="multipart/form-data">
foo:<input type="text" name="foo" />
bar:<input type="text" name="bar" />
<button type="submit">submit</button>
</form>

访问页面并提交后,可在 Chrome DevTools 网络面板看到,/submit 这个 POST 请求相关的信息:

Request Headers


Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNgS8sggyuawQSr8W

Form Data

------WebKitFormBoundaryNgS8sggyuawQSr8W
Content-Disposition: form-data; name="foo" 1

------WebKitFormBoundaryNgS8sggyuawQSr8W

Content-Disposition: form-data; name="bar" 2

------WebKitFormBoundaryNgS8sggyuawQSr8W--

这里 ------WebKitFormBoundaryNgS8sggyuawQSr8W 便是上面提到的 boundary ,用以分隔表单内容字段。

内容协商/Content Negotiation

前面提到客户端通过设置 Accept 请求头设置请求资源的类型,服务器根据 content negotiation 规则返回。

Content negotiation 是这么一种机制,同一 URI可响应多种资源,客户端可自行决定请求何种资源(譬如文档的语言,图片格式,文件编码类型)。





来自 MDN 展示内容协商流程的图片

内容协商包含两种方式:

  • 客户端通过设置请求头由服务器决定合适的类型进行返回(服务器驱动 )。
  • 服务器通过设置响应头中响应代码为 300 (Multiple Choices)或 406 (Not Acceptable)作为备用方案(客户端驱动)。

除了 Accept ,用于主动发起内容协商的请求头还有:

  • Accept-Charset:期望的字符集。
  • Accept-Encoding:期望的编码方式。
  • Accept-Language:期望的语言。

服务器驱动的内容协商

由客户端发送一组期望的类型,服务器根据自己的算法决定出最合适的类型进行返回,具体实现因服务器类型而异。服务器驱动是最常见的方式,但其也有一些明显的缺点:

  • 由于不是完全了解客户端的兼容性,服务器的返回有时候存在局限性。相反,客户端驱动的是服务器返回多个选择,客户端根据自己的情况选用最合适的,因为客户端自己最了解自己支持哪些。
  • 关于客户端的信息在多次请求中会冗余(当然,请求头冗余的情况在 HTTP/2 中有所缓解),也存在安全隐患(HTTP fingerprinting)。
  • 多种类型的资源被返回后,服务端的缓存策略不再那么有效并且实现会变得复杂。

客户端驱动的内容协商



来自 MDN 展示客户端驱动内容协商流程的图片

得到真实资源前多了一次选择的请求。

参考

Accept 与 Content-Type的更多相关文章

  1. Jsoup问题---获取http协议请求失败 org.jsoup.UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml.

    Jsoup问题---获取http协议请求失败 1.问题:用Jsoup在获取一些网站的数据时,起初获取很顺利,但是在访问某浪的数据是Jsoup报错,应该是请求头里面的请求类型(ContextType)不 ...

  2. jmeter报"msg":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported"的解决方法

    1.报"msg":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supporte ...

  3. 接入WxPusher微信推送服务出现错误:Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

    背景 使用WxPusher微信推送服务 ,可以及时的将服务的一些运行异常信息,发送到自己的微信上,方便了解服务的运行状态(PS:这个服务是免费的). 你可以在这里看到WxPusher微信推送服务的接入 ...

  4. Jsoup获取部分页面数据失败 org.jsoup.UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml.

    用Jsoup在获取一些网站的数据时,起初获取很顺利,但是在访问某浪的数据是Jsoup报错,应该是请求头里面的请求类型(ContextType)不符合要求. 请求代码如下: private static ...

  5. SharePoint自动化系列——Add content type to list.

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 将创建好的content type(若是跨web application需要事先publish c ...

  6. SharePoint自动化系列——Content Type相关timer jobs一键执行

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 背景: 在SharePoint Central Administration->Monito ...

  7. 转载 SharePoint【Site Definition 系列】– 创建Content Type

    转载原地址:  http://www.cnblogs.com/wsdj-ITtech/archive/2012/09/01/2470274.html Sharepoint本身就是一个丰富的大容器,里面 ...

  8. the request doesn't contain a multipart/form-data or multipart/form-data stream, content type header

    the request doesn't contain a multipart/form-data or multipart/form-data stream, content type header ...

  9. Springs Element 'beans' cannot have character [children], because the type's content type is element-only

    Springs Element 'beans' cannot have character [children], because the type's content type is element ...

  10. springboot 报错 Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

    开始 controller 方法写的是 @RequestMapping( value = "/add", method = RequestMethod.POST ) public ...

随机推荐

  1. java面向对象中四种权限(private,protected,public,友好型)详解

    转自http://blog.csdn.net/a1237871112/article/details/50926975 及http://blog.csdn.net/blackmanren/articl ...

  2. bzoj 1426 收集邮票

    f[i]:当前已拥有i种邮票,还需要买的邮票数的期望值. g[i]:当前已拥有i种邮票,还需要的钱的期望值. 每张邮票初始都是1元钱,每买一张邮票,还没购买的邮票每张都涨价1元.  f[i]=1+(n ...

  3. window 7 安装Jmeter并配置https录制脚本

    安装与环境配置: http://blog.csdn.net/hhuangdanfeng/article/details/51564765 http://blog.csdn.net/u010573212 ...

  4. TensorFlow从1到2(九)迁移学习

    迁移学习基本概念 迁移学习是这两年比较火的一个话题,主要原因是在当前的机器学习中,样本数据的获取是成本最高的一块.而迁移学习可以有效的把原有的学习经验(对于模型就是模型本身及其训练好的权重值)带入到新 ...

  5. MySQL 复制 - 性能与扩展性的基石 3:常见问题及解决方案

    主备复制过程中有很大可能会出现各种问题,接下来我们就讨论一些比较普遍的问题,以及当遇到这些问题时,如何解决或者预防问题发生. 1 数据损坏或丢失 问题描述:服务器崩溃.断电.磁盘损坏.内存或网络错误等 ...

  6. 再遇angular(angular4项目实战指南)

    这两天看了看angular4的文档,发现他和angular1.X的差别真的是太大了,官方给出的那个管理英雄的Demo是一个非常好的入门项目,这里给出一个管理个人计划的小项目,从头至尾一步一步讲解如何去 ...

  7. kubernetes实践之三:深入理解Pod对象

    一.Pod定义 最小部署单元 一组容器集合 一个pod中的容器共享网络命名空间 Pod是短暂的 二.Pod容器分类 基础容器 维护整个Pod的网络命名空间 初始化容器 先于业务容器开始执行,在应用启动 ...

  8. 【响应式编程的思维艺术】 (5)Angular中Rxjs的应用示例

    目录 一. 划重点 二. Angular应用中的Http请求 三. 使用Rxjs构建Http请求结果的处理管道 3.1 基本示例 3.2 常见的操作符 四. 冷热Observable的两种典型场景 4 ...

  9. HTML文档编写规范

    (1)HTML标记是由尖括号包围的关键词.所有标记均以“<”开始,以“>”结束.结束的标记在开始名称前加上斜杠“/”.例如头部标记格式如下所示:<head> ……</he ...

  10. Android底部导航栏(可滑动)----TabLayout+viewPager

    [TabLayout] ①TabLayout是选项卡,在屏幕空间有限的情况下,对不同的空间进行分组.属于android support design,更多的用于新闻上,如果放在底部也可做底部导航栏 ② ...