资讯详情

资讯详情

fetch polyfill的核心秘密:650行源码如何用Promise包装XHR,whatwg-fetch源码完整精读

fetch polyfill的核心秘密650行源码如何用Promise包装XHRwhatwg-fetch源码完整精读【免费下载链接】fetchA window.fetch JavaScript polyfill.项目地址: https://gitcode.com/gh_mirrors/fe/fetchwhatwg-fetch 是一个经典的 fetch polyfill垫片项目它用不足 650 行 JavaScript核心文件实际 642 行把旧浏览器中的 XMLHttpRequestXHR包装成基于 Promise 的window.fetchAPI让老浏览器也能像现代浏览器一样写异步请求代码。本文带你完整精读这份源码揭开 fetch polyfill 的 3 个核心秘密 项目速览一个「只在需要时生效」的 polyfill信息说明包名whatwg-fetchpackage.json 中版本 v3.6.20核心源码单文件 fetch.js共 642 行支持浏览器Chrome、Firefox、Safari 6.1、IE 10见 README.md类型标注配套的 Flow 类型定义 fetch.js.flow整个项目最克制的设计藏在源码最后 6 行——浏览器已有原生 fetch 时一行代码都不会生效// 只在浏览器缺少原生 fetch 时才安装垫片 if (!g.fetch) { g.fetch fetch g.Headers Headers g.Request Request g.Response Response } 源码位置fetch.js另外 fetch.js 还打了fetch.polyfill true标记方便你区分当前用的是原生还是垫片实现。️ 源码地图650 行里只有 5 个主角精读前先看整体结构fetch.js 按职责恰好分为 5 个模块模块行号范围职责HeadersL86-L165请求/响应头全部小写化存储支持for...of迭代BodyL222-L340共享的「身体处理」混入text()/json()/blob()/arrayBuffer()RequestL350-L461封装请求选项method、credentials、signal、缓存策略ResponseL463-L510封装响应status、ok、headers及error()/redirect()静态方法fetchL526-L633核心中的核心用 Promise 包装 XHR 发起请求 记忆技巧前 4 个是「数据容器」只有最后的fetch函数真正干活。所以精读源码重点永远在 fetch.js 这 100 来行。 秘密一Promise 如何「翻译」XHR 的 4 个事件fetch polyfill 的灵魂就是一个「事件翻译器」——把 XHR 的回调事件翻译成 Promise 的resolve/rejectexport function fetch(input, init) { return new Promise(function(resolve, reject) { var request new Request(input, init) var xhr new XMLHttpRequest() xhr.onload function() { /* resolve(new Response(...)) */ } xhr.onerror function() { /* reject(...) */ } // ... xhr.send(typeof request._bodyInit undefined ? null : request._bodyInit) }) } 完整实现fetch.js。四个事件的翻译对照表XHR 事件Promise 行为源码位置onload成功收到响应resolve(new Response(body, options))fetch.jsonerror网络失败reject(TypeError: Network request failed)fetch.jsontimeout超时reject(TypeError: Network request timed out)fetch.jsonabort手动取消reject(DOMException: AbortError)fetch.js两个新手最容易忽略的细节所有回调都套在setTimeout(..., 0)里如 fetch.js把 resolve/reject 推迟到下一个宏任务保证 Promise 一定异步结算行为在各浏览器上完全一致。响应头是「现场解析」的XHR 只能返回原始头字符串parseHeaders()负责把它逐行拆成键值对并装进Headers实例还顺带绕过了 IE11 core-js 的一个经典正则 bugfetch.js。 秘密二Body 混入模式——一套方法Request 和 Response 共用text()、json()、blob()、arrayBuffer()这些读「身体」的方法Request 和 Response 都需要源码却没有复制两份而是用「混入」注入Body.call(Request.prototype) // 第 461 行 Body.call(Response.prototype) // 第 483 行 分别见 fetch.js 与 fetch.js。Body()函数fetch.js把方法直接挂到this上一行call就完成了代码复用——这就是 650 行能写满 5 个 API 的关键。Body 里还有 3 个值得记住的设计一次读取保护consumed()守卫给响应打上bodyUsed标记二次读取直接返回被 reject 的 PromiseAlready readfetch.jsjson()只是text()的链式延伸this.text().then(JSON.parse)一行搞定fetch.js自动补content-type_initBody会根据身体类型字符串/Blob/表单自动设置请求头省去手工配置fetch.js 秘密三藏在细节里的兼容性功夫这份 polyfill 要兼容到 IE 10处处是「向下兼容」的巧思兼容场景源码解法能力探测开头的support对象逐一探测 Blob、FormData、URLSearchParams、ArrayBuffer按能力降级fetch.jsHTTP 方法大写化9 个标准方法GET/POST…统一转为大写fetch.js缓存禁用cache: no-store通过在 URL 上追加_时间戳实现缓存破坏fetch.jsCookie 策略credentials选项映射到xhr.withCredentialsfetch.js二进制响应优先responseTypeblob不支持则退回arraybufferfetch.js本地文件file://协议下状态码异常时强制按 200 处理fetch.js响应 URL 不可靠老浏览器退回读取X-Request-URL响应头兜底fetch.js请求取消监听 AbortSignal 的abort事件触发xhr.abort()请求完成后移除监听fetch.js错误类型缺失无原生DOMException时手工造一个继承 Error 的替身fetch.js✅ 一键安装与三个常见坑npm install whatwg-fetch --save导入import whatwg-fetch即自动生效无需其他配置针对极老浏览器还需额外引入一个 Promise polyfill说明见 README.md。⚠️ 官方 README 特别提醒的 3 个坑Caveats 章节404 / 500 不会 rejectHTTP 错误状态被视为「成功」需自行检查response.statusCookie 兼容性跨浏览器请显式传credentials: same-origin不要依赖默认值redirect 选项受 XHR 限制只支持 follow 模式error/manual会被忽略。如果需要获取源码本地研读git clone https://gitcode.com/gh_mirrors/fe/fetch 源码导读从哪些文件读起fetch.js —— 642 行核心源码本文主角fetch.js.flow —— Flow 类型定义对照阅读能快速弄清每个参数类型README.md —— 官方用法、Caveats 与浏览器支持清单CHANGELOG.md —— 563 行版本演进史记录了各浏览器 bug 的修复过程rollup.config.js Makefile —— 查看如何打包出 UMD 版本test/test.js test/karma.config.js —— 跨浏览器含 Web Worker 场景自动化测试矩阵 小结三句话记住 fetch polyfillPromise 是 XHR 的「翻译器」onload走 resolveerror / timeout / abort 走 reject全部用setTimeout(0)保证异步结算Body 混入是精简的秘诀一行Body.call(prototype)让 Request 和 Response 共享 4 种读体方法650 行代码只服务一个目标让老浏览器里也能优雅地写fetch(...).then(...)而且现代浏览器中原生实现存在时它会自动让位。这份源码堪称「小而美」的教科书级案例——读完它你会同时理解 Promise、XHR、Header 规范与 polyfill 设计四件事 【免费下载链接】fetchA window.fetch JavaScript polyfill.项目地址: https://gitcode.com/gh_mirrors/fe/fetch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →