三、fetch()的第二个参数:定制 HTTP 请求

fetch()的第一个参数是 URL,还可以接受第二个参数,作为配置对象,定制发出的 HTTP 请求。

  1. fetch(url, optionObj)

上面命令的optionObj就是第二个参数。

HTTP 请求的方法、标头、数据体都在这个对象里面设置。下面是一些示例。

(1)POST 请求

  1. const response = await fetch(url, {
  2. method: 'POST',
  3. headers: {
  4. "Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
  5. },
  6. body: 'foo=bar&lorem=ipsum',
  7. });
  8. const json = await response.json();

上面示例中,配置对象用到了三个属性。

  • method:HTTP 请求的方法,POSTDELETEPUT都在这个属性设置。
  • headers:一个对象,用来定制 HTTP 请求的标头。
  • body:POST 请求的数据体。

注意,有些标头不能通过headers属性设置,比如Content-LengthCookieHost等等。它们是由浏览器自动生成,无法修改。

(2)提交 JSON 数据

  1. const user = { name: 'John', surname: 'Smith' };
  2. const response = await fetch('/article/fetch/post/user', {
  3. method: 'POST',
  4. headers: {
  5. 'Content-Type': 'application/json;charset=utf-8'
  6. },
  7. body: JSON.stringify(user)
  8. });

上面示例中,标头Content-Type要设成'application/json;charset=utf-8'。因为默认发送的是纯文本,Content-Type的默认值是'text/plain;charset=UTF-8'

(3)提交表单

  1. const form = document.querySelector('form');
  2. const response = await fetch('/users', {
  3. method: 'POST',
  4. body: new FormData(form)
  5. })

(4)文件上传

如果表单里面有文件选择器,可以用前一个例子的写法,上传的文件包含在整个表单里面,一起提交。

另一种方法是用脚本添加文件,构造出一个表单,进行上传,请看下面的例子。

  1. const input = document.querySelector('input[type="file"]');
  2. const data = new FormData();
  3. data.append('file', input.files[0]);
  4. data.append('user', 'foo');
  5. fetch('/avatars', {
  6. method: 'POST',
  7. body: data
  8. });

上传二进制文件时,不用修改标头的Content-Type,浏览器会自动设置。

(5)直接上传二进制数据

fetch()也可以直接上传二进制数据,将 Blob 或 arrayBuffer 数据放在body属性里面。

  1. let blob = await new Promise(resolve =>
  2. canvasElem.toBlob(resolve, 'image/png')
  3. );
  4. let response = await fetch('/article/fetch/post/image', {
  5. method: 'POST',
  6. body: blob
  7. });