fetch 传统 Web 应用程序中大多数 XMLHttpRequest 的可行替代方案
这个 fetch()
函数是一种在浏览器中以编程方式发出 Web 请求的基于 Promise 的机制。此项目是一个实现标准子集的PolyFill。足以使 fetch
传统 Web 应用程序中大多数 XMLHttpRequest 的可行替代方案。
阅前须知
1、如果你再使用中发现了一个问题,请不要急着提交 Issues,不要在这个项目中打开一个问题除非您在不支持的旧版本浏览器中进行测试 window.fetch
。一定要看这个自述文件,特别是 警告 部分,可能有一个已知的解决问题的方法。
2、如果你有麻烦 向另一个域提出请求,不同的子域或端口号也构成另一个域,请熟悉 CORS 请求规范。因为 CORS 需要服务器通过实现特定的 HTTP 响应头来参与,所以设置或调试通常是非常重要的。CORS 完全由浏览器的内部机制处理,这种填充不会影响这些机制。
3、这个项目 在 Node.js 环境下不工作。它只适用于网页浏览器。您应该确保您的应用程序不会试图在服务器上打包和运行这个包。
4、如果您有一个新功能的想法 fetch
, 提交功能请求到 规范存储库。
安装
npm install whatwg-fetch --save
作为使用 npm 的替代方案,您可以fetch.umd.js
。UMD 发行版与 AMD 和 CommonJS 模块加载器兼容,并通过 <script>
标签。
你还需要一个 Promise 兼容解决方案,我们建议 taylorhakes/promise-polyfill 体积小,并且和 Promises/A+ 完全兼容。
使用方法
引入
引入后将自动注册 window.fetch
及有关的 APIs:
import 'whatwg-fetch'
window.fetch(...)
如果出于某种原因,您需要访问PolyFill实现,则可以通过导出获得该实现:
import {fetch as fetchPolyfill} from 'whatwg-fetch' window.fetch(...) // use native browser version fetchPolyfill(...) // use polyfill implementation
例如,这种方法可用于中止功能在实现本机但过时版本的FETCH的浏览器中,不支持中止。
若要与webpack一起使用,请将此包添加到entry
在应用程序入口点之前的配置选项:
entry: ['whatwg-fetch', ...]
HTML
fetch('/users.html')
.then(function(response) {
return response.text()
}).then(function(body) {
document.body.innerHTML = body
})
JSON
fetch('/users.json')
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
响应元数据
fetch('/users.json').then(function(response) {
console.log(response.headers.get('Content-Type'))
console.log(response.headers.get('Date'))
console.log(response.status)
console.log(response.statusText)
})
Post Table
var form = document.querySelector('form')
fetch('/users', {
method: 'POST',
body: new FormData(form)
})
Post JSON
fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Hubot',
login: 'hubot',
})
})
文件上传
var input = document.querySelector('input[type="file"]')
var data = new FormData()
data.append('file', input.files[0])
data.append('user', 'hubot')
fetch('/avatars', {
method: 'POST',
body: data
})
警告
- 许下的诺言
fetch()
不会拒绝HTTP错误状态即使响应是HTTP 404或500。相反,它将正常地解决,并且它只会拒绝网络故障或任何阻止请求完成的事情。 - 为了在发送和接收cookie时获得最大的浏览器兼容性,请始终提供
credentials: 'same-origin'
选项,而不是依赖于默认设置。 - 在这个多边形填充中并不支持所有的提取标准选项。例如
redirect
和cache
指令被忽略。 keepalive
不受支持,因为它涉及到同步的XHR,这是这个项目不愿意做的事情。
处理 HTTP 错误状态
有fetch
承诺拒绝HTTP错误状态,即在任何非2xx状态下,定义一个自定义响应处理程序:
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response
} else {
var error = new Error(response.statusText)
error.response = response
throw error
}
}
function parseJSON(response) {
return response.json()
}
fetch('/users')
.then(checkStatus)
.then(parseJSON)
.then(function(data) {
console.log('request succeeded with JSON response', data)
}).catch(function(error) {
console.log('request failed', error)
})
发送 Cookies
为 CORS 请求,使用 credentials: 'include'
要允许向其他域发送凭据,请执行以下操作:
fetch('https://example.com:1234/users', {
credentials: 'include'
})
的默认值 credentials
是 same-origin。
默认的credentials
但并不总是一样的。以下版本的浏览器实现了一个旧版本的FETCH规范,默认情况是 omit:
- Firefox 39-60
- Chrome 42-67
- Safari 10.1-11.1.2
如果以这些浏览器为目标,建议始终指定 credentials: 'same-origin'
显式地处理所有FETCH请求,而不是依赖默认的:
fetch('/users', {
credentials: 'same-origin'
})
注:应付 XMLHttpRequest的局限性,使用 credentials: 'omit'
在浏览器中,对于相同的域,此多边形填充是活动的,则不受尊重。在旧浏览器中,cookie将始终发送到相同的域。
接收 Cookies
与 XMLHttpRequest 一样,Set-Cookie
从服务器返回的响应标头是 禁止标头名 因此无法以编程方式读取 response.headers.get()
。相反,浏览器有责任处理正在设置的新 Cookie,如果适用于当前 URL。除非它们仅限于 HTTP,否则新的 Cookie 将通过 document.cookie
。
Redirect modes
The Fetch specification defines these values for the redirect
option: "follow" (the default), "error", and "manual".
Due to limitations of XMLHttpRequest, only the "follow" mode is available in browsers where this polyfill is active.
获取响应 URL
由于XMLHttpRequest的限制,response.url
HTTP在旧浏览器上重定向后,该值可能不可靠。
解决方案是配置服务器以设置响应HTTP报头 X-Request-URL
在可能发生的任何重定向之后,转到当前 URL。无条件地设置它应该是安全的。
# Ruby on Rails controller example
response.headers['X-Request-URL'] = request.url
如果您需要可靠,此服务器解决方案是必要的。response.url
在 Firefox<32,Chrome<37,Safari 或 IE 中。
中止请求
这种填充支架可中止的获取API。但是,中止获取需要使用两个额外的DOMAPI:AbortController和AbortSignal。通常,不支持FETCH的浏览器也不支持AbortController或AbortSignal。因此,您需要包括一种额外的填充要使这些API中止获取,请执行以下操作:
import 'yet-another-abortcontroller-polyfill'
import {fetch} from 'whatwg-fetch'
// use native browser implementation if it supports aborting
const abortableFetch = ('signal' in new Request('')) ? window.fetch : fetch
const controller = new AbortController()
abortableFetch('/avatars', {
signal: controller.signal
}).catch(function(ex) {
if (ex.name === 'AbortError') {
console.log('request aborted')
}
})
// some time later...
controller.abort()
浏览器支持
- Chrome
- Firefox
- Safari 6.1+
- Internet Explorer 10+
注意:诸如 Chrome、Firefox、MicrosoftEdge 和 Safari 等现代浏览器包含 window.fetch
。因此,这种 polyfill 的代码对这些浏览器没有任何影响。如果你认为你遇到了一个错误 window.fetch
是在任何这些浏览器中实现的,您应该向该浏览器供应商提交一个问题,而不是该项目。
相关链接
github 地址:https://github.com/github/fetch
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论