什么是 Content-Type 头
在http响应头或请求头中会看到一个名为Content-Type
的头信息,它表示的就是文档的类型信息(Multipurpose Internet Mail Extensions or MIME type 即 MIME type
)
一个url其实就是一个远程文件的地址,通常一个文件可以通过后缀名来区分文件类型,但是浏览器通过url访问文件并不会使用后缀名来判断,而是使用content-type这个头来判断,这也是为什么一个html可以有不同的后缀名,甚至不要后缀都可以,只有content-type这个头设置正确即可
Content-type 头结构
Content-type表示的是文档类型,它是有一个固定的结构的
type/subtype
// 或带参数的
type/subtype;parameter=value
这里的type
表示的是一个文件的大类别,例如 文本文件(text)、视频文件(video)等
subtype
表示文件的子类别,例如,对于文本文件(text),其可能是常规文本(plain)、HTML文件(html)等。例如对于一个静态页来说,其MIME type就是 text/html
文档类别是可以携带参数的,例如 text/plain;charset=UTF-8
type
type分为两种:单类型(discrete)和混合类型(multipart),其中,单类型就是文档就是一个类型的文件,例如html文件、视频文件等,而混合类型则表示多种类型的文件混合类型,典型的例如在表单提交时,会有文本、文件等多种类型混合提交的,或者接收的邮件中既有文本也有文件
discrete
text、image、font、video、model、audio、example、application等
multipart
对于混合类型的http响应,除了 Content-type 为 multipart/form-data
或者 multipart/byteranges
外,其他的类型都会被浏览器当作下载文件处理(Chrome右上角显示一个另存为的提示)
混合类型实际上也是要对每个子类型进行说明的,下文中有举例
混合类型的 type 有:multipart
和 message
MIME types举例
- application/octet-stream:默认的二进制文件类型,浏览器会直接显示“另存为”的提示
- text/plain:浏览器会直接显示,值得注意的是,浏览器不会将这种类型的文档解释为特定类型,例如你不能在里面写js或css等,浏览器不会主动解释
- text/css、text/html、text/javascript等
- image/apng、image/gif、image/jpeg、image/png、image/webp等
- video/webm、audio/webm。。。
multipart/form-data
这个头常见于表单提交的请求头中,以前一直没搞懂它是怎么运作的,这里做一个解释
对于这种混合类型的文档,它的content-type实际上也是由各个类型的单类型组合而成的。例如对于以下表单:
<form
action="http://localhost:8000/"
method="post"
enctype="multipart/form-data">
<label>Name: <input name="myTextField" value="Test" /></label>
<label><input type="checkbox" name="myCheckBox" /> Check</label>
<label>
Upload file: <input type="file" name="myFile" value="test.txt" />
</label>
<button>Send the file</button>
</form>
它里面有三个input标签,其中两个是文本类型,一个是文件类型,那么在提交时,实际的请求体为:
POST /cgi-bin/qtest HTTP/1.1
Content-Type: multipart/form-data; boundary=--aBoundaryString
Content-Length: 465
// 注:以下为请求体内容
--aBoundaryString
Content-Disposition: form-data; name="myTextField"
input of myTextField field
--aBoundaryString
Content-Disposition: form-data; name="myCheckBox"
on
--aBoundaryString
Content-Disposition: form-data; name="myFile"; filename="test.txt"
Content-Type: text/plain
Simple file.
--aBoundaryString--
可以看到,混合类型中,每个单独的类型都会被分解符号 --aBoundaryString
隔离开来,分界符前两个 --
不可省略,后面字符串随意。每个单独类型都有单独的http请求头,例如 Content-Type 或者 Content-Disposition,Content-Disposition 在这里指定文件名称或者表单中的字段名。紧接着就是这个类型的具体内容了。
一个真实的例子
或者在 https://www.w3school.com.cn/tiy/t.asp?f=eg_html_form_submit 测试以下代码,打开控制台,填写字段和文件,点击提交即可
<form action="/demo/demo_form.asp" enctype="multipart/form-data" method="post">
text: <input type="text" name="submit-name"><br/>
file: <input type="file" name="files"><br/>
<input type="submit" value="Send"/>
</form>
参考
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
https://blog.adamchalmers.com/multipart/