通过Content-Type,理解多样的HTTP协议

Content-type的作用

content-typehttp请求头中的一个字段,他用于指示请求体或者响应体数据的MIME类型

进一步理解就是:web应用中大部分数据的传输使用的都是http协议,content-type用于指示请求和响应中body传输数据的类型,可以参考chrome devtools中的network对于网络请求的分类,如下:

这其中除了WS代表websocket,其他网络请求的载体几乎都是http

js文件为例:

这里的content-type说明了该文件是js文件;

除了js文件,css文件,html文件,图片等也都是通过http传输,其各自的content-type区分了各自的类型

这里是针对相应的content-type进行分类,而fetchxhr请求载体也是http,但是此时响应的content-type就不是统一的一种,xhr/fetch在这里被统一划分成一类

Xhr/Fetch请求的Content-type

对于非ajax请求,其目的大部分都是为了获取某文件,所以请求方法是get,而get请求的请求头没有content-type,这是因为get没有请求体,其参数是拼接在url中的,因此无需content-type

对于Restful请求,get,post,put,delete,patch,其实可以简单理解为区分请求类型的一个字段而已,其本质差别仅仅是一个字段中数据的区别而已,只不过在约定俗成中,将各类型分配了各自的意义。

ajax请求,载体是xhr/fetch,随着http协议作用的丰富化,往往会有获取之外的更新等操作,因此会有post等方式

针对前端发起的方式不同,请求的所携带的数据组织方式也不相同,因此通过content-type进行标注,以供后台进行处理。

不携带请求体的请求

getdelete请求的标准用法下,一般不携带请求体,因此标准的get请求不携带content-type

携带请求体的请求

post,put,patch

json

content-typeapplication/json,示例如下

js 复制代码
fetch('http://localhost:9000', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({a:1})
})

实际发出的请求是这个样子的:

内容被编码成字符串放到请求体中发送

表单

content-typeapplication/x-www-form-urlencoded,示例如下

html 复制代码
<form action="http://localhost:9000" method="post" >
    <input type="text" name="name" value="John">
    <input type="text" name="age" value="19">
    <input type="submit" value="Upload">
</form>
js 复制代码
fetch('http://localhost:9000', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: 'username=John&age=19'
})

以上两者实现的效果是相同的,最后发出的结果是:

多个参数被&相连接以发送

文件上传的分块表单请求

content-typemultipart/form - data

content-type允许请求体分块传输,常用于上传文件的场景;

分块的多个请求,通过唯一的边界字符串间隔,并且会在content-type中标明

当表单包含上传文件时,则必须使用multipart/form - data
当使用FromData对象构建参数时,content-type默认使用multipart/form - data

示例:

html 复制代码
    <form action="http://localhost:3000" method="post" enctype="multipart/form - data">
        <input type="text" name="username" value="John">
        <input type="file" name="avatar" id="avatar">
        <input type="submit" value="Upload">
    </form>
js 复制代码
    const formData = new FormData();
    formData.append('username', 'John');
    const fileInput = document.getElementById('avatar');
    const file = fileInput.files[0];//获取File对象
    formData.append('avatar', file);

    fetch('http://localhost:3000', {
        method: 'POST',
        body: formData
        //默认使用multipart/form - data
    })

以上两者实现效果相同,最后发送的结果是:

http响应的content-type

Web应用几乎所有的资源都是通过HTTP传输的,包括访问网页看到的内容以及交互的js文件,当然包括XHR/Fetch请求;HTTP响应的content-type囊括了这些内容的所有类型

当访问网页时,率先用到的是html文件:

当继续加载时,用到的其他文件会逐渐继续通过http,协议传输过来

得益于打包工具chunk的划分,实现了这样用到时加载的效果,以此类推,其他文件(css,图片等)也是这样加载进来的

XHR/Fetch

当使用XHR/Fetch请求时,后端往往通过json的方式响应数据

流式下载

content-typeapplication/octet-stream

以qq官网下载为例

为二进制流式传输,通常用于文件下载

流式传输相比于Fetch到文件的整个二进制再触发下载有很大区别:流式传输无需在内存中存放一整个文件,而是处理和存储传输的小块数据;流式传输可以根据网络状况动态调整传输速率,在网络不稳定或带宽有限的情况下,能够更好地适应等等

非Xhr/Fetch的请求content-type?

对于Web应用需要获取某个文件,例如刚开始加载时候的index.html,是直接通过get请求该文件的url获取到的,类似直接在浏览器的地址栏输入url一样:两者都是为了获取这个文件。得益于打包软件的chunk和浏览器按需加载,每个资源文件都被划分了一个独特的url来标识该文件,这和url的本意统一资源标识符非常吻合;详见 HTTP的发展和URL含义的拓展:todo

当浏览器拿到该文件后,根据响应的content-type决定该文件的处理方式,如text/javascript就存放在本地等待被导入使用,如application/octet-stream就触发浏览器的下载功能,因此content-type来标识内容类型是非常关键的

上面说到get请求不携带请求体,因此这些为了获取文件的get请求也就不带有content-type

注意:需要区分请求的content-type和响应的content-type

总结

content-type是一个非常关键的http头,对于请求,该属性可以告知服务端如何处理请求体,而对于响应,该属性会告知浏览器应该如何对待返回的数据,丰富的content-type决定了http属性的适用性非常广泛,与其相关的url也不仅限于标识网络上的一个特定资源的符号。

恰如当初HTTP/0.9刚发布时,为url取名为统一资源标识符,人们只认为url只是标识网络资源,他们也很难想象往后的岁月里HTTP的发展如此迅速,功能变得如此强大,url从最开始获取资源也开始拓展到发送、更新、删除如此丰富的含义,这也可能导致了很多人对统一资源标识符的命名不甚理解

而随着更多新的HTTP版本的发布,未来Web应用将会变成什么样子呢?是不是也会突破今天人们对Web的固有思维呢?

无论如何,技术的更迭绝对是益处更甚的好事,我们不应该因为自己掌握的技术被迭代而感到悲伤,更应该为更合理化的技术更迭而感到开心,学习永远是人生中应该一直保持的根本,恰如Ai蓬勃发展的今天,以往信息检索被极大简化,我们可以将Ai当作知识渊博的名师,这本应该是好事,而对于取代我们工作的担忧,毕竟今天还没发生呢对吧!

人生大多数的烦恼和悲伤都源于对昨天的悔恨和明天的担忧,但是却一直忽略了最关键的今天

相关推荐
LyaJpunov1 小时前
HTTPS全解析:从证书签发到TLS握手优化
网络协议·http·https
你曾经是少年2 小时前
HTTPS
网络协议·http·https
2501_915918412 小时前
多账号管理与自动化中的浏览器指纹对抗方案
websocket·网络协议·tcp/ip·http·网络安全·https·udp
-九斤-5 小时前
http和https的区别
网络协议·http·https
whoarethenext5 小时前
https的发展历程
网络协议·http·https
摸鱼仙人~5 小时前
HTTP 响应状态码总结
网络·网络协议·http
Suckerbin6 小时前
基于HTTP头部字段的SQL注入:SQLi-labs第17-20关
网络·笔记·网络协议·安全·http·网络安全
c语言中的小小白12 小时前
【Linux网络】————HTTP协议详解
网络·网络协议·http
Hello.Reader19 小时前
ngx_http_keyval_module动态键值管理
网络协议·nginx·http
爱吃烤鸡翅的酸菜鱼1 天前
【SpringMVC】详解cookie,session及实战
java·http·java-ee·intellij-idea