网络请求

@Fetch
Overview
.Fetch 是 W3C 的一种请求标准;不是第三方库,与 Vue、JQuery 无关
.是原生的 JavaScript,是 Window 的方法,属于 BOM 范畴
.下一代 Ajax 技术,基于 Promise 方式处理数据 - 返回结果是 Promise
.语法简介明了;除了IE,多数浏览器都兼容
.既可以访问远程数据,也可以访问本地数据
.需要拼接参数;需要二次封装
.以下各案例使用回调函数 callback,简化代码可以使用 异步等待 asyn-await
.更多信息,请访问 Using_FetchMDN - fetchFetch_API接口调用 - fetchfetch - 请求数据
fetch(url)
console.dir(fetch);
Syntax
.拿到数据需要 2次 处理
.第一个 then() 返回的 Response 对象,包含了一些元数据和方法,但不直接包含请求返回的实际数据;要获取实际的 JSON 数据,需要调用 res.json() 方法将 Response 对象解析为 JSON 数据,并返回一个新的 Promise
.第二个 then() 处理解析后的 JSON 数据
.在响应的原型[[Prototype]] Response中,可以看到相关的函数,他们仍然是一个 Promise 对象,所以需要 2次 返回才能拿到结果
fetch( url, {
  method: '',
  headers: {
    'Content-Type': 'application/json'
  },
  body: ''
} )
  .then( res => res.json() )
  .then( res => {
    console.log( 'success ', res )
  } )
Configuration
method(String):HTTP 请求方法,Get 获取数据 | Post 提交数据 | Delete 删除数据 | Put 更新数据;默认为 GET
body(String):HTTP 请求的参数;POST 时使用
headers(Object):HTTP 请求头,如 content-type 的常见值为 application/json、application/x-www-form-urlencoded
如果数据是 json 格式,可以省略 header 配置项;具体还要看服务器端的适配情况
Response

根据请求的数据类型,返回的结果分别有:

res.json():得到 JSON 对象,同 JSON.parse(responseText) 一样;应用最广泛
res.text():得到文字|字符串
res.formData():得到 FormData 表单对象
res.blob():得到 Blob对象,如图片等多媒体对象
[] 获取本地/远程 .json 数据 - 在开发者视图的控制台查看获取结果
多数静态托管平台做了代理,可以直接访问;否则需要进行代理处理;详细操作请参考 fetch with json - Bilibili
fetch('https://glpla.github.io/utils/data/rank/20240203.json')
  .then(res => res.json())
  .then(res => console.log(res))
[] text()
请求本地/远程文本文件 .txt
fetch('./tmp.txt')
  .then(res => res.text())
  .then(res => console.log(res))
请求本地/远程 .html,实现模块化;不需要写完整的 html 结构,只写业务结构即可;见底部版权
fetch('../../common/drill.html')
.then(res => res.text())
.then(res => {
  document.getElementById('require').innerHTML = res;
})
[] formData() - 请求表单
[] blob() - 请求图片并渲染
blob
fetch('https://glpla.github.io/utils/avatar/avatar0.png')
  .then(res => res.blob())
  .then(res => img.src = URL.createObjectURL(res))
指定 accept 获取特别类型的图片,如去除水印、获取特定类型的图片 - 和浏览器和后端服务器有关
默认图片,url是png,另存为是avif
https://png.pngtree.com/recommend-works/png-clipart/20250101/ourmid/pngtree-cartoon-deer-standing-png-image_14982249.png
指定获取为png
fetch('https://png.pngtree.com/recommend-works/png-clipart/20250101/ourmid/pngtree-cartoon-deer-standing-png-image_14982249.png', {
  headers: {
    'Accept': 'image/png'
  }
})
  .then(response => response.blob())
  .then(blob => {
    const url = URL.createObjectURL(blob);
    img.value = url;
    console.log(img.value);

  })
  .catch(error => console.error('Error:', error));
      
注意
以上请求没有响应异常
fetch 请求不会抛出错误,即使是 404 或 500 错误 - A Fetch API promise will be rejected only in case of network failure.
应根据响应状态 ok 或状态码 status 判断结果
fetch('https://codilime.com/')
  .then(response => {
    if (!response.ok) {
      throw Error(`HTTP error: ${response.status}`);
    }
    return response.json();
  })
  .then(console.log)
  .catch((err) => {
    console.log(err.message)
  });
如果要处理异常,可以使用 catch()
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:3000/clerk/2002"
ok: false
redirected: false
status: 404
statusText: "Not Found"
type: "cors"
url: "http://localhost:3000/clerk/2002"
下例中,第一个 then 中通过 throw new Error 抛出了一个错误;这个错误会被后续的 catch 块捕获。因此,从技术上讲,不需要在第一个 then 中再单独处理异常;但是,如果你希望在第一个 then 中更细致的处理异常,可以选择在这里添加额外的逻辑
fetch('/utils/data/cart.json')
.then(response => {
  if (!response.ok) {
    throw new Error('Network response was not ok ' + response.statusText);
  }
  return response.json();
})
.then(data => {
  console.log(data);
})
.catch(error => {
  console.error('There was a problem with the fetch operation:', error);
})
.finally(() => {
  console.log('Fetch operation completed.');
});