聊一聊Content-Type

2,414 阅读4分钟

Content-Type和POST结合用于前端请求

  • Content-Type首字母即可大写也可小写

  • Content-Type在headers对象中配置

   headers: {
      'Content-Type': 'application/json'
   }
  • Content-Type设置与get请求无关,一般与post请求相关

  • 当用form表单提交时 Content-Type 默认为'application/x-www-form-urlencoded'。当用XHR提交时,Content-Type默认为'application/json'

  • Content-Type:'multipart/form-data' 一般用于上传文件时使用,多用于form表单提交 multipart:多重的。 当使用xhr形式提交时和application/json提交时的数据格式一样

  • Content-Type为'application/x-www-form-urlencoded'时提交数据的方式为"a=123&b=456&c=[1,2,3]"。但我们一般都是对象形式的写法,所以需要转换成以&符号拼接的形式 这也是为什么需要qs序列化的原因。因为这样后台才能正确的解析提交的数据

 {a:123,b:456,c:[1,2,3]}=>a=123&b=456&c=[1,2,3]
  • 当Content-Type为'application/json'时需要以json形式提交
 body: JSON.stringify({ a: 123, b: [1,2,3] })
 // or
 body: '{"a":123,"b":456}'

Content-Type用于后端响应,用于指定输出文件的类型

常见的有一下几种属性

'text/html' // 用于指定html文件

'text/plain' // html的源码会显示到页面上

'text/css' // 用于指定css文件

'image/jpg' // 用于指定图片格式

'aplication/javascript' // 用于指定js文件

'application/json' // 用于指定请求接口的数据格式

它们经常与'charset=utf-8'结合使用 例如:'Content-Type': 'text/html;charset="utf-8"'。否则解析时可能会造成乱码

fs.readFile('index.html', function(err, data) {

  if (err) {
      res.writeHeader(404, {
          'Content-Type': 'text/html;charset="utf-8"' // 用res.write写入需要加 charset="utf-8"否则会乱码
      })
      res.write('<h1>404</h1><p>你要找的页面被LEO吃了</p>');  //因为content-type设置的是text/html所以可以直接解析
      res.end()
  } else {
      res.writeHeader(200, {
          'Content-Type': 'text/html'
      })
      res.end(data)
  }

})     

form表单形式提交测试结果

当enctype="application/x-www-form-urlencoded"或者 enctype="multipart/form-data" 两者提交的内容是一样的,并没有什么区别

提交之后的数据


------WebKitFormBoundaryAehrCayXmChOAGwO
Content-Disposition: form-data; name="name"

小明
------WebKitFormBoundaryAehrCayXmChOAGwO
Content-Disposition: form-data; name="password"

123456
------WebKitFormBoundaryAehrCayXmChOAGwO
Content-Disposition: form-data; name="file"; filename="picture.jpg"
Content-Type: image/jpeg


------WebKitFormBoundaryAehrCayXmChOAGwO--

首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车。如果传输的是文件,还要包含文件名和文件类型信息。不知道为什么没有生成二进制内容。消息主体最后以 --boundary-- 标示结束。 这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利

form表单提交与xhr提交的区别

  • form表单提交没有跨域问题,xhr提交会有跨域问题
  • form表单指定enctype='multipart/form-data' 可以上传大文件
  • form表单提交之后会重新载入新的页面,可以用 e.preventDefault()禁止掉重载,如果带https会跳转到新页面,不带https会在本路由下添加action路径,xhr不会重载页面
  • xhr常用的有三种提交方式。application/json提交与multipart/form-data提交并无太大区别[常见情况是在后端做区分],提交的格式都差不多。form表单只有两种提交方式。两种方式也无太大区别[常见情况也是后端做区分]

new formDate()的使用场景

  • 可以将form表单中的name属性以键值对的形式传递输出
  • 可以处理文件形式和new blob()对象
  • 原型上面部署了Symbol.iterator方法,并且指向了entries 所以可以被for of遍历

坑:使用xhr方式提交append()方法追加的数据,无法提交给服务器,但是使用fetch()却可以。解决办法 使用for of 循环 手动添加

   let params = {}
   for (let [key, value] of formData) {
       params[key] = value
   }

view parsed 查看已解析

view source 查看源

view URL encoded 查看编码的URL

view decoded 查看已解码

Form Data 表格数据

request payload 请求有效载荷

general 常规的

query string parameters 查询字符串参数

参考文章

四种常见的 POST 提交数据方式

Node中POST请求的正确处理方式

NodeJS http服务端获取POST请求数据