您的位置:

深度探讨axios中的Content-Type

在前端开发中,我们经常需要向后端发送HTTP请求并处理后端返回的数据。而axios是一个既简单易用又功能强大的HTTP请求库,Axios支持多种 Content-Type 类型,包括 application/json、application/x-www-form-urlencoded 等,本文将从多个方面详细阐述Axios中的Content-Type。

一、Content-Type简介

Content-Type 是 HTTP 请求头部的一部分,用于指定请求或响应实体的媒体类型。

// 请求头中的 Content-Type
Content-Type: application/json

// 响应头中的 Content-Type
Content-Type: text/html;charset=UTF-8

HTTP 协议和 MIME 类型规定了一系列标准的媒体类型和子类型,具体的 Content-Type 在HTTP请求头或响应头中,用来描述请求体媒体类型和响应体媒体类型。

二、默认Content-Type

axios 在默认情况下使用的 Content-Type 是 application/json;charset=utf-8 。

// 使用axios发送POST请求
axios.post('/api/user', {
  name: 'example'
}).then(function (response) {
  console.log(response);
})
// 发送请求头为以下内容
Content-Type: application/json;charset=utf-8

可以看到,在axios未指定 Content-Type 类型时,默认使用 application/json;charset=utf-8 。

三、Content-Type与请求体的对应关系

根据 HTTP 请求的方法和不同的请求体格式,对 Content-Type 的类型也有不同的规定。

1. application/json

当使用 application/json 类型是,请求体应该被 JSON.stringify 序列化为字符串。

// 发送POST请求,并指定Content-Type为application/json
axios({
  method: 'post',
  url: '/user',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  },
  headers: {
    'Content-Type': 'application/json'
  }
});

// 发送请求头为以下内容
Content-Type: application/json;charset=utf-8
// 请求体为以下内容
{"firstName":"Fred","lastName":"Flintstone"}

2. application/x-www-form-urlencoded

当使用 application/x-www-form-urlencoded 类型时,请求体应该以 name1=value1&name2=value2 的方式进行编码。

// 发送POST请求,并指定Content-Type为application/x-www-form-urlencoded
axios({
  method: 'post',
  url: '/user',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  },
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
});

// 发送请求头为以下内容
Content-Type: application/x-www-form-urlencoded;charset=utf-8
// 请求体为以下内容
firstName=Fred&lastName=Flintstone

3. multipart/form-data

当使用 multipart/form-data 时,请求体应该是一个包含二进制数据的 multipart/form-data 表单。这种方式比较适合文件上传等场景。

// 发送POST请求,并指定Content-Type为multipart/form-data
var formData = new FormData();
formData.append('avatar', file);

axios.post('/user', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
});

// 发送请求头为以下内容
Content-Type: multipart/form-data;charset=utf-8; boundary=----WebKitFormBoundaryE19zNvXGzXaLvS5C
// 请求体为以下内容
------WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg"
Content-Type: image/jpeg

����JFIF��H�H�������FExifMM*���(�������(����(��2��i��i���Adobe d�    ���&��Photoshop 3.0 8BIM������8BIM%��x???'$��4�%G  ���S�Adobed���     �� "��� �� �}!1AQa"q2���#B��R��$3br�
...
------WebKitFormBoundaryE19zNvXGzXaLvS5C--

四、Content-Type与响应体的对应关系

同样的,响应头的 Content-Type 字段可以反映出响应体的媒体类型和编码格式。axios 默认会将响应体当做 JSON 解析,自动将响应体转换成 JavaScript 对象或数组。但是,除了 JSON 类型外,还有其他媒体类型。

1. application/json

当返回的数据是 JSON 格式时,axios 会自动解析为 JavaScript 对象,方便开发人员处理数据。

// 获取JSON格式数据
axios.get('/api/data').then(function (response) {
  console.log(response.data);
})

// 返回JSON格式数据
Content-Type: application/json;charset=utf-8
// 响应体为以下内容
{
  "name": "example",
  "age": 18
}

2. text/plain

当返回的数据是纯文本时,axios 会使用 utf-8 编码的字符串返回响应体数据。

// 获取纯文本数据
axios.get('/api/text').then(function (response) {
  console.log(response.data);
})

// 返回纯文本格式数据
Content-Type: text/plain;charset=utf-8
// 响应体为以下内容
hello world

3. application/octet-stream

当返回的数据是流数据时,axios 会将其作为二进制数据进行处理,需要开发人员自己进行处理。

// 获取流数据
axios.get('/api/stream', {responseType: 'stream'}).then(function (response) {
  console.log(response.data);
})

// 返回流格式数据
Content-Type: application/octet-stream;charset=utf-8
// 响应体为以下内容
���

五、Content-Type的其他应用场景

通过设置 Content-Type 来使前端对请求和响应进行更精细控制,下面的案例中每个操作的目标不同,却都是通过设置 Content-Type 实现的。

1. 下载文件

有时我们需要将一个字符串或二进制数据转换为文件下载到本地,可以通过设置 Content-Type 为 application/octet-stream,在浏览器中自动触发下载操作。

// 下载文件
axios.get('/api/download', {
  responseType: 'arraybuffer',
  headers: {
    'Content-Type': 'application/octet-stream'
  }
}).then(function (response) {
  const blobData = new Blob([response.data]);
  const downloadUrl = URL.createObjectURL(blobData);
  const anchor = document.createElement('a');
  anchor.href = downloadUrl;
  anchor.download = 'example.txt';
  document.body.appendChild(anchor);
  anchor.click();
  document.body.removeChild(anchor);
});

// 返回流格式数据
Content-Type: application/octet-stream;charset=utf-8
// 响应体为文件内容
example content

2. Base64编码

在使用一些服务端API时,需要将数据编码成base64格式,并设置Content-Type为application/octet-stream,并将返回值的data字段解析成base64字符串。

// 将文本转换为Base64编码
axios.post('/api/encode', {
  data: 'hello world'
}, {
  headers: {
    'Content-Type': 'application/octet-stream'
  }
}).then(function (response) {
  console.log(response.data);
});

// 返回流格式数据
Content-Type: application/octet-stream;charset=utf-8
// 响应体为以下内容
aGVsbG8gd29ybGQ=

3. 上传图片

为了能够处理文件上传,我们需要将表单中的二进制数据作为multipart/form-data类型的请求发送到服务端。此时需要设置Content-Type为multipart/form-data,并使用FormData对象进行表单数据的封装。

// 上传图片
const formData = new FormData();
formData.append('image', file);

axios.post('/api/image', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
}).then(function (response) {
  console.log(response.data);
});

// 发送请求头为以下内容
Content-Type: multipart/form-data;charset=utf-8; boundary=----WebKitFormBoundaryE19zNvXGzXaLvS5C
// 请求体为以下内容
------WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg"
Content-Type: image/jpeg

����JFIF��H�H�������FExifMM*���(�������(����(��2��i��i���Adobe d�    ���&��Photoshop 3.0 8BIM������8BIM%��x???'$��4�%G  ���S�Adobed���     �� "��� �� �}!1AQa"q2���#B��R��$3br�
...
------WebKitFormBoundaryE19zNvXGzXaLvS5C--

六、总结

本文详细阐述了Axios中的Content-Type,在使用axios发送请求时,需要根据不同的请求类型和场景,设置不同的Content-Type来使得请求和响应达到更精细的控制。同时,axios的默认值为application/json;charset=utf-8,当我们需要使用其他类型时,需要手动设置Content-Type字段。通过前面的案例可以看出,在客户端和服务端进行数据交互时设置Content-Type是非常重要的。