HTTP系列--Content type

    技术2022-07-10  90

    其他网址

    HTTP content-type | 菜鸟教程

    POST提交数据之---Content-Type的理解; - 龙恩0707 - 博客园

    简介

            form表单中可以定义enctype属性,该属性的含义是在发送到服务器之前应该如何对表单数据进行编码。默认的情况下,表单数据会编码为"application/x-www-form-unlencoded"。

    <form method="post" action="show-data.php" enctype="multipart/form-data"> ... </form>

    Content-Type有数百个,下面例举了一些常见的

     常见的媒体格式类型如下:

    text/html : HTML格式text/plain :纯文本格式text/xml : XML格式image/gif :gif图片格式image/jpeg :jpg图片格式image/png:png图片格式

    以application开头的媒体格式类型:

    application/xhtml+xml :XHTML格式application/xml: XML数据格式application/atom+xml :Atom XML聚合格式application/json: JSON数据格式application/pdf:pdf格式application/msword : Word文档格式application/octet-stream : 二进制流数据(如常见的文件下载)application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

    另外一种常见的媒体格式是上传文件之时使用的:

    multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

    上面的Content-Type,我们只认得就好,但是下面有4种是需要我们清楚他们的区别及牢记在心的。

    application/x-www-form-urlencoded

    简介

    特点

    支持GET/POST等方法。 如果请求类型type是GET的话,那么格式化的字符串将直接拼接在url后发送到服务端; 如果请求类型是POST, 那么格式化的字符串将放在http body的Form Data中发送。所有数据变成键值对的形式 key1=value1&key2=value2的形式特殊字符需要转义成utf-8编号,如空格会变成 ;所有浏览器都支持

    作用:

    1:最常见的POST提交数据方式。 2:原生form默认的提交方式(可以使用enctype指定提交数据类型)。 3:jquery,zepto等默认post请求提交的方式。

    form表单中post默认提交方式的数据

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> </head> <body> <div id="app"> <form action="http://www.example.com" method="POST"> <p>username: <input type="text" name="fname" /></p> <p>age: <input type="text" name="age" /></p> <input type="submit" value="提交" /> </form> </div> </body> </html>

    请求转化:

    使用ajax的方式提交

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script> </head> <body> <div id="app"> <div class="btn">发送post请求</div> </div> <script> var obj = { "name": 'CntChen', "info": 'Front-End', }; $('.btn').click(function() { $.ajax({ url: 'www.example.com', type: 'POST', dataType: 'json', data: obj, success: function(d) { } }) }); </script> </body> </html>

     转化之后:

    multipart/form-data

    简介

    特点

    键值对的形式。value可以是text,也可以是file。可同时传多个键值对使用表单上传文件时,必须指定表单的 enctype属性值为 multipart/form-data。请求体被分割成多部分,每部分使用 boundary分割;

    实例

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> </head> <body> <div id="app"> <form action="http://www.example.com" method="POST" enctype="multipart/form-data"> <p>username: <input type="text" name="fname" /></p> <p>age: <input type="text" name="age" /></p> <input type="submit" value="提交" /> </form> </div> </body> </html>

     转化之后

    application/json

    简介

    问题引出

            http请求中,ContentType都是默认的值 application/x-www-form-urlencoded, 这种编码格式的特点是:name/value值对,每组之间使用&连接,而name与value之间是使用 = 连接,比如 key=xxx&name=111&password=123456; 键值对一般的情况下是没有什么问题的,是很简单的json形式,比如如下:

    { a: 1, b: 2 }

    它会解析成 a=1&b=2这样的,但是在一些复杂的情况下,比如需要传一个复杂的json对象,也就是对象嵌套数组的情况下,比如如下代码:

    { obj: [ { "name": 111, "password": 22 } ] }

            这样复杂的对象,application/x-www-form-urlencoded这种形式传递的话, 会被解析成 obj[0]['name']=111&obj[0].['password']=2这样的。然后再转成json形式;

            对于一些复杂的数据对象,对象里面再嵌套数组的话,建议使用application/json传递比较好,开发那边也会要求使用application/json。因为他们那边不使用application/json的话,使用默认的application/x-www-form-urlencoded传递的话,开发那边先要解析成如上那样的,然后再解析成json对象,如果对于比上面更复杂的json对象的话,那么他们那边是很难解析的,所以直接json对象传递的话,对于他们来说更简单。

            通过json的形式将数据发送给服务器。json的形式的优点是它可以传递结构复杂的数据形式,比如对象里面嵌套数组这样的形式等。

    实例

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script> </head> <body> <div id="app"> <div class="btn">发送post请求</div> </div> <script> $('.btn').click(function() { $.ajax({ url: 'http://www.example.com', type: 'POST', dataType: 'json', contentType: 'application/json', data: JSON.stringify({a: [{b:1, a:1}]}), success: function(d) { } }) }); </script> </body> </html>

    如上代码,在浏览器运行后,发现跨域了,如下图所示:

    理解ajax跨域设置 ContentType: application/json

            在使用ajax跨域请求时,如果设置Header的ContentType为 application/json,它会发两次请求,第一次先发Method为OPTIONS的请求到服务器,这个请求会询问服务器支持那些请求方法(比如GET,POST)等。如果这个请求支持跨域的话,就会发送第二个请求,否则的话在控制台会报错,第二个请求不会请求。如下我们做个简单的demo,不跨域的如下:

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script> </head> <body> <div id="app"> <div class="btn">发送post请求</div> </div> <script> $('.btn').click(function() { $.ajax({ url: 'http://localhost:8081/api.json', type: 'POST', dataType: 'json', contentType: 'application/json', data: JSON.stringify({a: [{b:1, a:1}]}), success: function(d) { } }) }); </script> </body> </html>

    如下图所示(json格式提交的数据会显示 Request Payload):

    application/xml 和 text/xml

            XML 麻烦,推荐用 JSON 。

            XML(Extensible Markup Language) 是 SGML(Standard Generalized Markup Language)的一个子集。SGML 也分配了媒体类型( text/sgml 和 application/sgml),但兼容性较差。XML 有两种 MIME 媒体类型:text/xml 和 application/xml。

    RFC2376 文档 定义了application/xml 和 text/xml 媒体类型。RFC7303 文档 也定义了application/xml 媒体类型。RFC3023 文档 一次定义了application/xml 和 text/xml 等所有的 XML 相关媒体类型。

    application/xml 媒体类型

    推荐使用。如果 MIME 用户代理或 Web 用户代理不支持这个媒体类型,会转为 application/octet-stream,当做二进制流来处理。application/xml 实体默认用 UTF-8 字符集。Content-type: application/xml; charset="utf-8" 或 <?xml version="1.0" encoding="utf-8"?> 都可以生效。

    text/xml 媒体类型

    如果 MIME 用户代理或 Web 用户代理不支持这个媒体类型,会将其视为 text/plain,当做纯文本处理。text/xml 媒体类型限制了 XML 实体中可用的编码类型(例如此时支持 UTF-8 但不支持 UTF-16,因为使用 UTF-16 编码的文本在处理 CR,LF 和 NUL 会导致异常转换)。text/xml 实体在 XML 头指定编码格式无效,必须在 HTTP 头部的 Content-Type: 中指定才会生效(例如 <?xml version="1.0" encoding="utf-8"?> 无法设置字符集,Content-Type: text/xml; charset="utf-8" 则可以)。没有设置字符集时默认使用“us-ascii”字符集。

    Content-Type的使用

    request 的Content-Type

            一般我们在开发的过程中需要注意客户端发送请求(Request)时的Content-Type设置,特别是使用ajax的时候,如果设置得不准确,很有可能导致请求失败。比如在spring中,如果接口使用了@RequestBody,spring强大的自动解析功能,会将请求实体的内容自动转换为Bean,但前提是请求的Content-Type必须设置为application/json,否正就会返回415错误。 注:415 错误是 Unsupported media type,即不支持的媒体类型。

    建议:

        如果是一个restful接口(json格式),一般将Content-Type设置为application/json; charset=UTF-8;     如果是文件上传,一般Content-Type设置为multipart/form-data     如果普通表单提交,一般Content-Type设置为application/x-www-form-urlencoded

    response的Content-Type

            服务端响应(Response)的Content-Type最好也保持准确,虽然一般web开发中,前端解析响应的数据不会根据Content-Type,并且服务端一般能自动设置准确的Content-Type,但是如果乱设置某些情况下可能会有问题,比如导出文件,打开图片等。如果在spring项目里使用@ResponseBody,spring会将响应的Content-Type设置为application/json;charset=UTF-8;,可能会导致文件无法导出,需要注意下。

    response的Content-Type设置建议:

        一般情况下不需要显示设置;     如果是文件导出,Content-Type 设置为 multipart/form-data,并且添加一个Content-Disposition设置为attachment;fileName=文件.后缀。     注:Content-Disposition是Content-Type的扩展,告诉浏览器弹窗下载框,而不是直接在浏览器里展示文件。因为一般浏览器对于它能够处理的文件类型,如txt,pdf 等,它都是直接打开展示,而不是弹窗下载框。

    下面的一个设置response的Content-Type的例子:

        未准确设置response的Content-type的情况,客户端将json数据当成普通文本     content-type →text/html;charset=UTF-8

        准确设置response的Content-type的情况,客户端将json数据自动解析     content-type →application/json;charset=UTF-8

    Processed: 0.018, SQL: 9