HTTP请求入参类型解读
Content-Type
在HTTP请求中,Content-Type
请求头用于指示资源的MIME类型,即请求体的媒体类型。它告诉服务器实际发送的数据类型是什么,以便服务器能够正确地解析和处理这些数据。Content-Type
可以有多种值,每种值都对应着不同的媒体类型。以下是一些常见的Content-Type
值及其区别:
application/x-www-form-urlencoded
- 这是最常见的表单数据提交方式,表单数据被编码为键值对,类似于URL的查询字符串(但不需要URL的
?
前缀)。例如:key1=value1&key2=value2
。 - 它通常用于HTML表单的提交,其中
enctype
属性被设置为application/x-www-form-urlencoded
(这是默认值)。 - 它不支持上传文件。
multipart/form-data
- 当需要上传文件时,
enctype
应该被设置为multipart/form-data
。这种类型的数据会将表单数据编码为一条消息,其中包含多个部分,每个部分都可以是文本或文件。 - 它使用分界线(boundary)来分割不同的部分,每个部分都有自己的
Content-Type
和Content-Disposition
(如form-data
)等头部信息。 - 它支持文件上传和二进制数据。
application/json
- 当请求体是JSON格式的数据时,应使用
application/json
作为Content-Type
。JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。 - 它广泛用于AJAX和RESTful API中,以提供和接收结构化的数据。
text/plain
- 当请求体是纯文本时,可以使用
text/plain
。这意呀着数据以纯文本形式发送,没有HTML或XML等标记。 - 它通常用于发送简单的文本消息或日志数据。
text/html
- 尽管在HTTP请求中不常见(因为HTML通常用于响应体),但在某些情况下,如果客户端想要发送HTML代码给服务器,可能会使用
text/html
作为Content-Type
。 - 这通常不是最佳实践,因为发送HTML代码到服务器可能会带来安全风险。
application/xml
或text/xml
- 当请求体是XML格式的数据时,可以使用
application/xml
或text/xml
。XML是一种标记语言,用于数据的存储和传输。 application/xml
表示XML数据是应用程序的一部分,而text/xml
则更强调数据的文本性质。然而,在实践中,这两者之间的区别并不明显,很多服务器和客户端都能处理这两种类型。
每种Content-Type
都对应着不同的数据格式和用途,选择合适的Content-Type
对于确保数据被正确解析和处理至关重要。
入参形式
在HTTP请求中,request payload
(请求负载)和formData
(表单数据)都用于向服务器发送数据,但它们的使用场景和编码方式有所不同。
request payload
request payload
是在发送POST或PUT请求时,请求体(Body)中包含的数据。这个数据可以是JSON、XML等格式,用于向服务器传递复杂的数据结构。当使用application/json
作为Content-Type
时,请求体中的数据通常就是JSON格式的request payload
。
特点:
- 适用于发送JSON、XML等结构化的数据。
Content-Type
通常设置为application/json
、application/xml
等。- 数据不是通过表单提交的方式发送的,因此不直接对应HTML表单。
formData
formData
是模拟HTML表单数据的一种编码方式,主要用于发送包含文件的请求。当HTML表单的enctype
属性设置为multipart/form-data
时,表单中的数据就会以formData
的格式发送。在AJAX请求中,也可以使用JavaScript的FormData
对象来手动构造这样的数据。
特点:
- 适用于需要上传文件的场景。
- 数据以
multipart/form-data
编码方式发送,可以包含多个字段和文件。 - 字段和文件以
Content-Disposition
和Content-Type
等HTTP头部信息分隔。 - 在JavaScript中,可以通过
FormData
API构造和发送formData
。
示例
JavaScript中发送formData
let formData = new FormData();
formData.append('username', 'exampleUser');
formData.append('file', fileInput.files[0]); // 假设fileInput是一个文件输入元素
fetch('/upload', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
在这个例子中,formData
对象包含了一个文本字段username
和一个文件file
,它们都将以multipart/form-data
的格式发送到服务器。
JavaScript中发送JSON作为request payload
let data = {
username: 'exampleUser',
// 其他字段...
};
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
在这个例子中,一个JavaScript对象被序列化成JSON字符串,并作为request payload
发送到服务器。这里使用的是application/json
作为Content-Type
。
常见的Request Content Type
发送表单数据FormData
application/x-www-form-urlencoded
和 multipart/form-data
是两种在HTTP请求中发送表单数据(form data)的常见内容类型(Content-Type)。它们各自有不同的使用场景和特性。
application/x-www-form-urlencoded
- 使用场景:主要用于发送不包含文件的简单表单数据。当HTML表单的
enctype
属性未被设置或显式设置为application/x-www-form-urlencoded
时,表单数据就会以这种方式发送。 - 数据编码方式:表单中的每个字段都被编码为
key=value
的形式,多个字段之间用&
字符连接。特殊字符(如空格、标点符号等)会被编码为%XX
格式的十六进制数(其中XX
是该字符的ASCII码的十六进制表示)。 - 示例:如果表单包含字段
name=John
和age=30
,则发送的数据可能看起来像这样:name=John&age=30
。 - 限制:由于编码方式和传输格式的限制,这种类型不适合用于发送大量数据或包含二进制数据的文件。
传参示例
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
//参数构造形式
const urlencoded = new URLSearchParams();
urlencoded.append("text", "测试123");
urlencoded.append("name", "lucy");
const requestOptions = {
method: "POST",
headers: myHeaders,
body: urlencoded,
redirect: "follow"
};
fetch("https://dict.youdao.com/keyword/key", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
上面代码中的参数构造形式还可以直接写成以下形式
const urlencoded = "text=测试123&name=lucy" // 等价于 上面的 urlencoded.toString()
如果你的参数是个json对象,可以通过下面的形式转换后,作为formData提交
const params = {
"test": "测试123",
"name": "lucy"
}
const urlencoded = Object.keys(params).map(key=>`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&')
multipart/form-data
- 使用场景:主要用于发送包含文件的表单数据。当HTML表单的
enctype
属性设置为multipart/form-data
时,表单数据就会以这种方式发送。 - 数据编码方式:数据被分割成多个部分(parts),每个部分都包含字段的
Content-Disposition
(描述字段名和可能的文件名)和Content-Type
(描述该部分数据的MIME类型)头部信息。文件内容作为其中一个或多个部分发送,而文本字段则以key=value
的形式编码并作为其他部分发送。 - 示例:一个包含文件和文本字段的表单提交时,请求体可能会包含多个部分,每部分都有自己的头部信息和数据内容。
- 优势:支持发送大量数据和包含二进制数据的文件,是上传文件的标准方式。
在支持FormData对象的执行环境中,可通过 new FormData来构造表单数据
const myHeaders = new Headers();
myHeaders.append"content-type","multipart/form-data");
const formdata = new FormData();
formdata.append("text", "申请开票");
formdata.append("name", "lucy");
const requestOptions = {
method: "POST",
headers: myHeaders,
body: formdata,
redirect: "follow"
};
fetch("https://dict.youdao.com/keyword/key", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
如果当前执行环境不支持FormData对象,可根据FormData的参数形式手工构造,也能达到相应效果。包含文件流的不建议
function generateSimpleId() {
return (
'----WebKitFormBoundary' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
)
}
function jsonToFormData(data, boundary) {
let arr = []
for (let key in data) {
arr.push(`\r\n--${boundary}\r\nContent-Disposition: form-data;name="${key}"\r\n\r\n${data[key]}`)
}
arr.push(`\r\n--${boundary}--`)
return arr.join('')
}
const boundary = generateSimpleId()
const myHeaders = new Headers();
myHeaders.append("content-type",`multipart/form-data;boundary=${boundary}`)
const params = {
"text": "test",
"name": "lucy"
}
const formdata = jsonToFormData(params,boundary)
const requestOptions = {
method: "POST",
headers: myHeaders,
body: formdata,
redirect: "follow"
};
fetch("https://dict.youdao.com/keyword/key", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
选择哪种类型?
- 如果你的表单只包含文本字段且不需要上传文件,那么
application/x-www-form-urlencoded
是一个简单且高效的选择。 - 如果你的表单需要上传文件,或者包含二进制数据,那么
multipart/form-data
是必需的。
在JavaScript中,你可以使用FormData
对象来构造这两种类型的请求体。FormData
对象会自动处理字段的编码和文件的上传,而无需你手动设置Content-Type
头部(尽管在某些情况下,你可能需要设置其他头部信息)。当使用fetch
或XMLHttpRequest
等API发送请求时,只需将FormData
对象作为请求体(body)即可。
发送payload
application/json
这种json格式传参是POST请求中常用的类型,其传参格式如下
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify({
"test": "测试123",
"name": "lucy"
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
fetch("https://dict.youdao.com/keyword/key", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));