Skip to content

fetch网络请求

1. 基本使用

js
fetch('http://localhost:3000/api/user')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.log(err))

2. 请求参数

js
fetch('http://localhost:3000/api/user', {
  method: 'POST',
  headers: {
      'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: '张三',
    age: 18
  })
})
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.log(err))

3.取消请求

js
// 创建一个控制器
const controller = new AbortController();
const signal = controller.signal;

fetch('http://localhost:3000/api/user', {
  signal  // 将控制器传递给fetch
})
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.log(err))

setTimeout(() => {
  controller.abort(); // 取消请求
}, 1000)

4.流式读取

js
const response = await fetch('/api/large-file');
const reader = response.body.getReader();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  
  // 处理分块数据(Uint8Array)
  const text = new TextDecoder('utf-8').decode(value, { stream: true });
  console.log('value:', text);
}

5.释放资源

js
reader.releaseLock(); // 释放锁
reader.cancel(); // 取消请求

6.请求超时

js
const controller = new AbortController();
const signal = controller.signal;

const timeout = setTimeout(() => {
  controller.abort();
}, 5000);

fetch('http://localhost:3000/api/user', {
  signal
})
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.log(err))

// 清除超时定时器
clearTimeout(timeout);

7.流式请求案例

js
try{
    // 发送请求
    let response = await fetch("",
      {
        method: "post",
        responseType: "stream",
        headers: {
          Authorization: "Bearer " + 'token',
          "Content-Type": "application/json",
        },
        body: {},
      }
    );
    // ok字段判断是否成功获取到数据流
    if (!response.ok) {
      throw new Error("Network response was not ok");
    }
    // 用来获取一个可读的流的读取器(Reader)以流的方式处理响应体数据
    const reader = response.body.getReader();
    // 将流中的字节数据解码为文本字符串
    const textDecoder = new TextDecoder('utf-8');
    let result = true;
    let sqlValue = ''
    while (result) {
      // done表示流是否已经完成读取  value包含读取到的数据块
      const { done, value } = await reader.read();
      if (done) {
        result = false;
        break;
      }
      // 拿到的value就是后端分段返回的数据,大多是以data:开头的字符串
      // 需要通过decode方法处理数据块,例如转换为文本或进行其他操作
      const chunkText = textDecoder
        .decode(value, { stream: true })
        .split("\n")
        .forEach((val) => {
          if (!val) return;
          try {
            // 后端返回的流式数据一般都是以data:开头的字符,排除掉data:后就是需要的数据
            // 具体返回结构可以跟后端约定
            let text = val?.replace("data:", "") || ""
            console.log(val, text, "输出分段返回的数据");
            sqlValue += text;
          } catch (err) {}
        });
    }
    console.log(sqlValue,'输出所有返回数据')
} catch(err) {}