Content-Type与表单提交数据类型

表单格式

类型区别:https://juejin.cn/post/6844904149809627149
MIME类型:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types
MIME类型

媒体类型(MIME类型),是一种标准,用来表示文档、文件或字节流的性质和格式,是互联网的一种定义的标准化

浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理URL,因此Web服务器在响应头中添加正确的MIME类型非常重要,如果配置不正确,浏览器可能会曲解文件内容,网站将无法正常工作,并且下载的文件也会被错误处理

// 写了就明确告诉浏览器这什么类型,如果不写,浏览器就按照自身的默认设置来处理,最终请求到的文件格式会体现在头字段Content-Type中
<script type="text/javascript">
<style type="text/css">

独立类型

独立类型表明了对文件的分类,可以是如下之一:

类型描述Content-Type典型示例
text表明文件是普通文本,理论上是人类可读text/plain, text/html, text/css, text/javascript
image表明是某种图像。不包括视频,但是动态图(比如动态gif)也使用image类型image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon
audio表明是某种音频文件audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav
video表明是某种视频文件video/webm, video/ogg
application表明是某种二进制数据application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf

Multipart类型

Multipart 类型表示细分领域的文件类型的种类,经常对应不同的 MIME 类型,这是复合文件的一种表现方式,如multipart/form-data 可用于联系 HTML Forms和 POST方法,此外 multipart/byteranges使用状态码206Partial Content来发送整个文件的子集,而HTTP对不能处理的复合文件使用特殊的方式:将信息直接传送给浏览器(这时可能会建立一个“另存为”窗口,但是却不知道如何去显示内联文件)

设置正确的MIME类型的重要性

很多web服务器使用默认的 application/octet-stream 来发送未知类型,出于一些安全原因,对于这些资源浏览器不允许设置一些自定义默认操作,导致用户必须存储到本地以使用,常见的导致服务器配置错误的文件类型如下所示:

  • RAR编码文件。在这种情况,理想状态是,设置真实的编码文件类型;但这通常不可能(可能是服务器所未知的类型或者这个文件包含许多其他的不同的文件类型)。这这种情况服务器将发送 application/x-rar-compressed 作为MIME类型,用户不会将其定义为有用的默认操作。
  • 音频或视频文件。只有正确设置了MIME类型的文件才能被<video>或<audio>识别和播放
  • 专有文件类型。是专有文件时需要特别注意。使用 application/octet-stream 作为特殊处理是不被允许的:对于一般的MIME类型浏览器不允许定义默认行为(比如“在Word中打开”)

POST传输格式

浏览器和接口进行通信过程中有两种传输格式:Form DataRequestPayload,使用 Content-Type 的值进行区分:

Content - Type请求格式
application/x-www-form-urlencodedformdata
application/jsonrequest payload
multipart/form-datarequest payload

multipart/form-data

  • 可用于HTML表单从浏览器发送信息给服务器

  • 作为多部分文档格式,它由边界线(一个由'--'开始的字符串,一般自动生成)划分出的不同部分组成,每一部分有自己的实体,以及自己的 HTTP 请求头 Content-DispositionContent-Type,(Content-Length 因为边界线作为分隔符而被忽略)

  • 在文件上传时最常用的格式

请求发送的格式如下:

Content-Type: multipart/form-data; boundary=一段用作分隔的字符

--用来用作分隔的字符串
Content-Disposition: form-data; name="myFile"; filename="img.jpg"
Content-Type: image/jpeg

数据内容B
--用来用作分隔的字符串
Content-Disposition: form-data; name="myField"

数据内容A
--用来用作分隔的字符串
...

区别

application/jsonapplication/x-www-form-urlencodedmultipart/form-data只是因为 Content-Type设置的不同,并不是数据提交方式的不同,这几种提交都会将数据放在 payload中,但是 chrome 浏览器的开发者工具会根据这个ContentType区分显示方式

  • application/json

    如果只是简单的ajax请求,请求的 header将自动设置为Content-Type: application/json,浏览器会简单的将提交的内容作为 payload 展示出来,这就是它所能做的,因为它不知道数据来自哪里

axios.post('/xxx', {
	username: '1',
    password: '1'
})

  • application/x-www-form-urlencoded

    如果提交了一个html表单并且配置上了method="post",并且设置了 Content-Type: application/x-www-form-urlencoded

    实际上,不用单独设置 enctype 也行,因为如果不设置,默认就是 application/x-www-form-urlencoded 格式

<form action="http://www.gegeda.online:3001" method="post" enctype="application/x-www-form-urlencoded">
    <input type="text" name="username">
    <input type="text" name="password">
    <button>Send the file</button>
</form>

  • multipart/form-data

    如果提交了一个html表单并且配置上了method="post",并且设置了 Content-Type: multipart/form-data

<form action="http://www.gegeda.online:3001" method="post" enctype="multipart/form-data">
    <input type="text" name="username">
    <input type="text" name="password">
    <button>Send the file</button>
</form>

  • text/plain

    传统的ajax请求时候,Content-Type 默认为 文本 类型,Request Payload会对非字符串做字符串转换,相当于数据执行了 toString 方法,对象格式的数据会丢失

    通过 xhr.send(JSON.stringify(obj)) 可修正要发的内容,相当于先转换为字符串再发送

<button id='btn' onclick="">发送AJAX</button>

let btn = document.querySelector('#btn')
btn.onclick = function() {
    var xhr = new XMLHttpRequest();
    xhr.timeout = 3000;
    var obj = {a: 1, b: 2};
    xhr.open('POST', 'http://www.gegeda.online:3001');
    xhr.send(obj);
    // xhr.send(JSON.stringify(obj))
}

payload解析

有时候前端提交表单数据,后端会拿不到值,是因为前后端对 payload 的解析方式不同,因此需要统一发送过去的数据格式

如:如果后端设置的是从对象里拿到数据,那就不能以 data1=x&data2=y 的形式提交数据,这样提交过去的数据后端将会无法解析

Content-Type的差异

  • 传统的ajax请求时候,Content-Type 默认为 文本 类型

  • 传统的form提交的时候,Content-Type 默认为 Form 类型

  • axios传递字符串的时候,Content-Type 默认为 Form 类型

  • axios传递对象的时候,Content-Type 默认为 JSON 类型

Content-Type的值,Form与非Form时,payload的区别

  • 都只支持字符串类型,不支持对象

  • Form需要传递的格式为a=1&b=2,类似GET请求的 QueryString格式

  • Form一般为JSON.stringify(formDataObject)形式:a:1,b:2

因此后端如果取不到值,无论何种形式传递,后端解析表单信息的时候,会考虑Content-Type。如果是JSON字符串的话,后端解析payload的内容时候,肯定要去解析JSON,如果是 key1=value1&key2=value2 的形式,则需要去分割字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值