首页
学习
活动
专区
圈层
工具
发布

Javascript fetch api无限制超时

JavaScript Fetch API 无限制超时问题解析

基础概念

Fetch API 是现代浏览器提供的用于发起网络请求的接口,它基于 Promise,比传统的 XMLHttpRequest 更简洁强大。默认情况下,Fetch API 没有内置的超时机制,这意味着如果服务器不响应,请求可能会无限期挂起。

为什么会无限制超时

  1. 设计决策:Fetch API 被设计为底层API,故意不包含超时功能,让开发者根据需要实现
  2. 与XMLHttpRequest的区别:传统XHR有timeout属性,但Fetch API没有类似设计
  3. 浏览器实现:不同浏览器可能有自己的默认超时,但这不属于规范

解决方案

方法1:使用AbortController实现超时

代码语言:txt
复制
const controller = new AbortController();
const signal = controller.signal;

// 设置超时时间
const timeout = 5000; // 5秒

// 设置超时定时器
const timeoutId = setTimeout(() => {
  controller.abort();
  console.log('请求超时');
}, timeout);

fetch('https://api.example.com/data', { signal })
  .then(response => {
    clearTimeout(timeoutId);
    if (!response.ok) {
      throw new Error('网络响应不正常');
    }
    return response.json();
  })
  .then(data => {
    console.log('成功获取数据:', data);
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('请求被中止:', error);
    } else {
      console.log('请求错误:', error);
    }
  });

方法2:使用Promise.race实现超时

代码语言:txt
复制
function fetchWithTimeout(url, options, timeout = 5000) {
  return Promise.race([
    fetch(url, options),
    new Promise((_, reject) =>
      setTimeout(() => reject(new Error('请求超时')), timeout)
    )
  ]);
}

fetchWithTimeout('https://api.example.com/data', {}, 5000)
  .then(response => {
    if (!response.ok) {
      throw new Error('网络响应不正常');
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('错误:', error));

方法3:封装为可复用函数

代码语言:txt
复制
async function fetchWithTimeout(resource, options = {}) {
  const { timeout = 8000 } = options;
  
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeout);

  const response = await fetch(resource, {
    ...options,
    signal: controller.signal  
  });
  
  clearTimeout(id);
  
  if (!response.ok) {
    throw new Error(`${response.status} ${response.statusText}`);
  }
  
  return response;
}

// 使用示例
fetchWithTimeout('https://api.example.com/data', { timeout: 5000 })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('错误:', error));

最佳实践建议

  1. 合理设置超时时间:根据应用场景设置不同的超时时间
    • 关键API:5-10秒
    • 非关键API:15-30秒
    • 文件上传/下载:更长或动态调整
  • 错误处理:区分超时错误和其他网络错误
  • 重试机制:对于超时请求可考虑实现指数退避重试
  • 全局配置:在大型应用中,建议统一封装fetch并配置默认超时

应用场景

  1. 需要稳定网络请求的SPA应用
  2. 对响应时间敏感的服务
  3. 移动端应用(网络环境不稳定)
  4. 需要防止长时间挂起的后台任务

注意事项

  1. AbortController在现代浏览器中支持良好,但旧版浏览器可能需要polyfill
  2. 中止的请求实际上可能仍在后台进行,只是浏览器不再处理响应
  3. 某些特殊请求(如流式响应)可能需要特殊处理
  4. 服务端也需要设置合理的超时时间以匹配客户端设置
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

JavaScript Fetch API 新手入门指南

开篇 自从Fetch API 问世以来,我们就能使用漂亮的语法发送HTTP Request 或取后台接口数据,这篇文章将会分享我自己常用的Fetch方法( GET、POST、搭配await 或promise.all...,通过天气数据开放平台可以取得许多气象资料(例如阿里云的API开放平台),下面的示例获取北京的当日气温,因为结果返回为json格式,所以在fetch取得数据之后,通过json()的方法处理数据,接着传递到下一层...error() 返回Response 的错误内容 05 Fetch 的Get 用法 Get 是Fetch 最简单的方法,使用Get 必须要将fetch 第二个参数里的method 设定为get,如果遇到跨域问题...; 08 兼容性 说了这么多,你一定关心这个API的兼容性,现代浏览器大部分还是支持的,可以放心使用,如下图所示: ? ?...Fetch API 的神奇,简化了许多原本较为复杂的用法,也让项目代码写起来更加干净易读好维护。更重要的是 JavaScript ES6 原生支持,你不需要安装任何依赖包,直接可以在项目中使用。

1.2K10
  • fetch api 浅谈

    作者:巫枫 fetch api浅谈 作为传说中的xhr替代品,现在fetch api已经被开始在一些前端项目中使用了,比如阿里的一些产品已经将jq的ajax模块切换到fetch下了。...个人感觉fetch api会渐渐替代xhr成为主流。 什么是fatch api呢,我们来看个例子。...api的使用,从上例中我们可以看出两点: 1、fetch api返回的是一个promise对象,使用es7提供的async/await特性,可以改写为 var myImage = document.querySelector...2、综合使用 fetch作为替换xhr的api,需要足够底层,这样,就需要支持各种场景的使用。下面是一些综合使用示例。...4、展望     xhr盛行多年,fetch api从写法上给前端带来了一些新的想法,这无疑是好的。

    2.6K00

    JavaScript中的Fetch

    Fetch 的核心在于对 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用于初始化异步请求的 global fetch。...得益于 JavaScript 实现的这些抽象好的 HTTP 模块,其他接口能够很方便的使用这些功能。 除此之外,Fetch 还利用到了请求的异步特性——它是基于 Promise 的。...Fetch 还提供了专门的逻辑空间来定义其他与 HTTP 相关的概念,例如 CORS 和 HTTP 的扩展。...区别 fetch 规范与 jQuery.ajax() 主要有三种方式的不同: 1.当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject, 即使响应的...2.fetch() 不会接受跨域 cookies;你也不能使用 fetch() 建立起跨域会话。其他网站的 Set-Cookie 头部字段将会被无视。 3.fetch 不会发送 cookies。

    2.2K20

    简单入门Fetch API

    简单入门Fetch API 前言 Fetch API是使用 JavaScript请求资源的优秀工具。虽然我们开发时可能是经常使用axios,但是实际上Fetch API也能做很多一样的事。...并且使用Fetch API不需要安装axios,所以我们做一些小案例,但是需要调接口的话,Fetch API便是很好的选择,不需要安装axios,也不需要像XMLHttpRequest 对象那样子需要较多步骤...基本用法 接口有需要可以到最后自取(express接口) 分派请求 只需要使用fetch()方法即可,传参为获取资源的URL。该方法返回一个Promise对象。...fetch('http://localhost:8088/getInfo?...() console.log(data) }) 图片 如果服务器没有响应导致浏览器超时的话,这时候就不会再执行then()方法的处理函数,而是执行catch()方法的,因为这时候的

    1.2K10

    PWA系列——Fetch API

    PWA系列——Fetch API 今天聊聊 xhr 的替代品 Fetch,在全局作用域中有个 fetch 方法方便使用。...使用 Fetch 我们需要了解 fetch、Request、Response、Headers 以及 Body,这几个都是使用 Fetch API 所需要了解的。...fetch 作为全局作用域中的 fetch,首先我们需要快速了解一下 fetch 方法如何调用(参考 MDN): 他可以接收一个 USVString 字符串或者一个 Request 对象(下文会讲到 Request...代码段 结合上篇文章介绍的 Cache API,我们尝试使用 Fetch 获取请求数据并保存缓存,然后每次刷新检测是否存在缓存,存在即获取缓存的数据: (async function () {...appendImg(blobData) } else { // 没有命中缓存则使用 fetch 发起请求并使用 Cache API 缓存 ?

    1.1K20

    Ajax 之战:XMLHttpRequest 与 Fetch API

    AJAX 是“Asynchronous JavaScript and XML”的缩写,尽管严格地说,开发人员并不需要使用异步方法、JavaScript 或 XML。...Fetch Fetch 是一个现代基于 promise 的 Ajax 请求 API,首次出现于 2015 年,在大多数浏览器中都得到了支持。...,在服务器和客户端使用相同的 API 有助于减少认知成本,还提供了在任何地方运行的同构 JavaScript 库的可能性。...超时支持 XMLHttpRequest 对象提供了一个 timeout 属性,可以将其设置为请求自动终止前允许运行的毫秒数;如果超时,就触发一个 timeout 事件来处理: const xhr =...XMLHttpRequest 也很稳定的,API 不太可能更新。Fetch 比较新,还缺少几个关键特性,虽然更新不太可能破坏代码,但你可以期待一些维护。 应该使用哪个 API ?

    2.7K20

    ES6 Fetch API基础教学

    在当ES6已经推出但还未普及的时候,如果有人问:“如何用JavaScript向服务器请求数据?”一定会有人回答用$.ajax。...$.ajax几乎是最简单又容易上手的请求方式了,不必再使用原生JavaScript中又长又臭的XMLHttpRequest(),在ES6中出现了替代ajax的 Fetch API。...它有以下优点:fetch API 使用 Promise 来处理异步操作,这使得链式调用更加简洁和易于管理。而 $.ajax 使用回调函数,这可能导致回调地狱(callback hell)的问题。...fetch 提供了更现代和简洁的语法,使得代码更易于编写和阅读。更清晰的错误处理。使用 fetch 不需要依赖 jQuery 或其他库,这减少了全局命名空间的污染。...GETGET 是请求中最基本的类型,在 Fetch 中默认的请求类型也是 GET 用起来就像下面:fetch('https://httpbin.org/get') .then((response)

    23910

    跟我一起探索 HTTP-Fetch API

    Fetch API Fetch API 提供了一个获取资源的接口(包括跨网络通信)。对于任何使用过 XMLHttpRequest 的人都能轻松上手,而且新的 API 提供了更强大和灵活的功能集。...这将在未来更多需要它们的地方使用它们,无论是 service worker、Cache API,又或者是其他处理请求和响应的方式,甚至是任何一种需要你自己在程序中生成响应的方式(即使用计算机程序或者个人编程指令...但是我们不建议这么做,它们更可能被创建为其他的 API 操作的结果(比如,service worker 中的 FetchEvent.respondWith。...除非你在init 对象中设置(去包含)credentials,否则fetch()将不会发送跨源 cookie 备注: 更多关于 Fetch API 的用法,参考使用 Fetch,以及一些概念 Fetch...Fetch 接口 fetch() 包含了 fetch() 方法,用于获取资源。 Headers 表示响应/请求的标头信息,允许你查询它们,或者针对不同的结果做不同的操作。

    47130
    领券