Fetch方法——一种简单合理的跨网络异步获取资源方式

向阳花7 / 2024-01-18 / 原文

Fetch API是一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。Fetch API提供了一个全局 fetch() 方法,一种简单,合理的来跨网络异步获取资源的方式。

一个基本的 fetch 请求:

fetch("http://localhost:4000/datas.json",{
    method: "POST",                           // *GET, POST, PUT, DELETE, etc.
    mode: "cors",                             // no-cors, *cors, same-origin
    cache: "no-cache",                        // *default, no-cache, reload, force-cache, only-if-cached
    credentials: "same-origin",               // include, *same-origin, omit
    headers: {
      "Content-Type": "application/json",     // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: "follow",                       // manual, *follow, error
    // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, 
    // same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    referrerPolicy: "no-referrer", 
    body: JSON.stringify({name: 'apple'}),     // body data 类型必须匹配请求头 "Content-Type" 
  })
  .then((response) => response.json())         //返回一个Promise,即response对象
  .then((data) => console.log(data));

json()方法返回一个 promise,该promise将响应 body 解析成 JSON 。

注意:仅当网络故障或请求被阻止时,从 fetch() 返回的 Promise 才会标记为 reject;当HTTP 状态码在 200 - 299 范围内,resolve 返回值的 ok 属性为 true,否则为 false。

请求添加验证凭据

需要在fetch请求中添加 credentials 属性。

credentials:'include' —— 浏览器发送包含凭据的请求

      'same-origin' —— 只在请求 URL 与调用脚本位于同一起源处时发送凭据

      'omit' —— 浏览器不在请求中包含凭据

例如:

fetch("http://localhost:4000/api/getData", {
    method: "get",
    credentials: "include",
}).then((response) => {
    return response.text();
}).then((data) => {
    console.log(data);
});

发送JSON数据的请求

JSON格式的数据请求与获取:

fetch("http://localhost:4000/api/getData", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",        // 发送json信息,设置Content-Type
    },
    body: JSON.stringify({ username: "example" }),
}).then((response) => {
    return response.json();                        // 把response中的body数据包装到Promise中并返回
}).then((data) => {
    console.log("Success:", data);
}).catch((error) => {
    console.error("Error:", error);
});

 fetch 上传文件

input file 上传文件,FormData() 方法获取文件:

const formData = new FormData();
const files = document.querySelector('input[type="file"][multiple]');

formData.append("title", "My job files");
for (let i = 0; i < files.files.length; i++) {
    formData.append(`files_${i}`, files.files[i]);
}

fetch("http://localhost:4000/api/getData", {
    method: "POST",
    body: formData,
}).then((response) => {
    return response.json();
}).then((result) => {
    console.log("Success:", result);
}).catch((error) => {
    console.error("Error:", error);
});

获取文件

fetch("http://localhost:4000/cats.jpg").then((response) => {
    if (!response.ok) {                                        // 响应状态码非 200 - 299
        throw new Error("Response OK is false.");
    }
    return response.blob();                                    // 获取图片
}).then((myBlob) => {
    document.createElement("img").src = URL.createObjectURL(myBlob);
}).catch((error) => {
    console.error("There has been a problem with fetch:", error);
});

Body 类定义了以下方法获取 body 内容:

  • Request.arrayBuffer() / Response.arrayBuffer()
  • Request.blob() / Response.blob()
  • Request.formData() / Response.formData()
  • Request.json() / Response.json()
  • Request.text() / Response.text()

这些方法都返回一个被解析后的 Promise 对象和数据。