FetchAPI

FetchAPI是HTML5中新增的异步请求API,FetchAPI基于新的JavaScript语言标准和HTML5相关的API进行了重新设计,用于取代老旧的XMLHttpRequest。FetchAPI和XHR的区别包括:

  1. 使用Promise实现异步操作
  2. 优化了API的设计,对HTTP请求的Request、Response、Headers等进行了合理拆分

有关兼容性,大多数现代浏览器都对FetchAPI有良好的支持,然而IE浏览器不支持FetchAPI,如果程序需要兼容IE浏览器则无法使用。

使用FetchAPI

由于FetchAPI是基于Promise实现的,因此我们可以直接使用async/await写法。下面例子中我们创建了一个异步函数,请求接口数据并解析JSON为对象后返回。

const fetchStudents = async function () {
    try {
        const rsp = await fetch('/students?classId=1', {
            method: 'GET'
        });
        const rspData = await rsp.json();
        return rspData;
    } catch (e) {
        console.log(e);
    }
};

fetch()函数接收两个参数:第1个参数一般为url字符串;第2个参数为可选的请求信息,包括请求方法、请求头、请求体数据等。

请求参数

URL请求参数

对于GET方式,我们需要通过URL来传递参数,FetchAPI对此没有特殊处理,我们需要拼接参数字符串。此时可以使用URLSearchParams对象构造查询参数,该工具类可以自动处理参数拼接和URL编码。

const params = new URLSearchParams();
params.append('name', 'Tom');
params.append('age', '18');

console.log(params.toString());

输出:

name=Tom&age=18

具体fetch()的使用前面已经介绍过,这里就不重复黏贴代码了。

JSON请求体

在接口的POST请求中,我们通常都是使用JSON传递请求参数,早期开发中还会用到XML的方式,但现在已经十分罕见了,这里我们只介绍JSON方式。例子如下:

const body = {
    name: 'Tom',
    age: 18
};

try {
    const rsp = await fetch('/add', {
        method: 'POST',
        headers: {
            'Content-type': 'application/json; charset=UTF-8',
        },
        body: JSON.stringify(body)
    });
    return await rsp.json();
} catch (e) {
    console.log(e);
}

这里要注意,发起JSON请求时我们需要设置请求选项的body参数,我们这里需要手动将对象序列化为JSON字符串;除此之外还需要设置Content-Type请求头。

表单请求参数

对于POST方式,除了最常用的XML或JSON请求体方式传递参数,我们也可以使用表单格式传递请求参数,表单则又分为application/x-www-form-urlencodedmultipart/form-data两种方式。

application/x-www-form-urlencoded

application/x-www-form-urlencoded和URL参数类似,也需要使用URLSearchParams工具类进行构造,例子如下。

const body = new URLSearchParams();
body.append('name', 'Tom');
body.append('age', '18');

try {
    const rsp = await fetch('/add', {
        method: 'POST',
        headers: {
            'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
        },
        body
    });
    return await rsp.json();
} catch (e) {
    console.log(e);
}

表单请求参数需要放在请求选项的body字段中,发起请求时会自动转换为编码好的字符串,此外还需要注意的一点是我们需要正确设置请求的Header。

multipart/form-data

multipart/form-data格式的表单一般用于内容较大的表单或是文件上传,此类型表单可以使用FormData对象构造,例子如下。

const body = new FormData();
body.append('name', 'Tom');
body.append('age', '18');

try {
    const rsp = await fetch('/add', {
        method: 'POST',
        body
    });
    return await rsp.json();
} catch (e) {
    console.log(e);
}

这里要特殊注意,multipart/form-data表单的请求头中需要带一个boundry参数,作为这种特殊表单格式的字段边界,然而该参数一般是随机生成的。此处fetch()的行为是,我们不需要设置任何Header,只需要设置body参数为FormData对象就可以了,发起请求时会自动识别并添加带boundryContent-Type请求头。例如:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2wGx5u1ATsl53i4D

文件上传

HTTP协议下,浏览器端的文件上传一般也都基于multipart/form-data格式的表单实现,其使用方法和上面文本表单相同。

const body = new FormData();
body.append('file', document.getElementById('file').files[0]);

对于大文件上传,我们也可以基于FileAPI对文件进行手动分片,然后通过FormData()对象构造请求格式,具体使用FetchAPI上传的写法和之前相同,这里就不重复黏贴代码了。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。