浏览器网络请求
ajax
ajax 其实并不是一个发请求的方式,它是多种技术的组合,是一个思想,全称为,Asynchronous JavaScript And XML 即异步 JavaScript 和 XML,并不能吧 ajax 和 XMLHttpRequest 划上等号。
ajax 的特点就是局部刷新页面,无需重载整个页面。
XHR 是实现 ajax 的一种手段
|
axios
基于 promise 对 XMLHttpRequest 的二次封装
其特点:
- 从浏览器中创建 XMLHttpRequests(不同环境)
- 从 node.js 创建 http 请求(不同环境)
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
navigator.sendBeacon
navigator.sendBeacon()
方法可用于通过 HTTP POST 将少量数据 异步 传输到 Web 服务器。
它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:XMLHttpRequest
)发送分析数据的一些问题。
语法
|
参数
url
url
参数表明data
将要被发送到的网络地址。data
可选data
参数是将要发送的ArrayBuffer
、ArrayBufferView
、Blob
、DOMString
、FormData
或URLSearchParams
类型的数据。
这个方法主要用于满足统计和诊断代码的需要,这些代码通常尝试在卸载(unload)文档之前向 Web 服务器发送数据。过早的发送数据可能导致错过收集数据的机会。然而,对于开发者来说保证在文档卸载期间发送数据一直是一个困难。因为用户代理通常会忽略在 unload
事件处理器中产生的异步 XMLHttpRequest
。
过去,为了解决这个问题,统计和诊断代码通常要在
- 发起一个同步
XMLHttpRequest
来发送数据。 - 创建一个 img,大部分用户代理会延迟卸载(unload)文档以加载图像。
- 创建一个几秒的 no-op 循环。
上述的所有方法都会迫使用户代理延迟卸载文档,并使得下一个导航出现的更晚。下一个页面对于这种较差的载入表现无能为力。
这就是 sendBeacon()
方法存在的意义。使用 sendBeacon()
方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能,这意味着:
- 数据发送是可靠的。
- 数据异步传输。
- 不影响下一导航的载入。
数据是通过 HTTP POST 请求发送的
**Fetch 相比 XHR **
- 使用场景比较多,Service Worker 环境里也能用,相比 xhr 只能运行在渲染进程内
- 同源请求也可以自定义不带 cookie,某些服务不需要 cookie 场景下能少些流量
- 可自定义重定向场景,xhr 只能 follow
- 自定义 cache mode ,xhr 只能借助 response header(Cache-Control…等)
- 可自定义 referrer
- 原生支持,不需要额外装包。
劣势:
劣势:
没有 timeout 事件(可以通过 race 封装实现流程控制,但这样不能中断连接;因为 abort 已经通过 AbortController 支持,也可以通过 abort 间接实现 timeout);
没有 progress 事件(上传、下载进度没有比较方便的实现方法);
tips:
fetch 可通过实验性的 abort 中断请求,
请求中断
XHR
|
当你调用abort()
方法时,如果请求还在进行中,它会立即被停止。正在进行的任何网络活动都会被停止,而且 XHR 对象会立即停止所有的事件监听器(例如onload
,onerror
等)。
如果成功中断请求,abort
事件会被派发,然后readystate
会变为UNSENT
。
请注意,一旦请求被中断,XHR 对象就不能再被用于发起新的请求。如果你需要再次发起请求,你需要创建一个新的 XHR 对象。
axios
在 axios 中,你可以使用取消令牌(CancelToken)来中断一个请求。以下是一个示例:
|
在上面的代码中,axios.CancelToken.source()
返回一个包含新的取消令牌和函数的对象。你可以把这个取消令牌传递给你的请求配置,然后在你需要取消请求的任何时候调用source.cancel()
。
当请求被取消时,axios promise 会被 reject,你可以在 catch 块中检查axios.isCancel(thrown)
以确定是否请求被取消。
fetch
使用 AbortController 来中断一个请求。以下是一个示例:
|
在上面的代码中,你创建了一个 AbortController
实例,并从中获取到了一个 signal。然后在你的 fetch 请求中,将这个 signal 传递给 fetch 请求的选项。
然后,当你需要中断这个请求的时候,你可以调用 controller.abort()
方法。这将会导致 fetch promise 被 reject,并且错误的 name 属性为 ‘AbortError’。你可以在 catch 块中检查这个属性,以确定是否请求被取消。
promise 可借助 promise.race 中断请求
利用这个特性,你可以创建一个延迟拒绝的 Promise,与你的请求 Promise 一起传递给Promise.race
,以实现中断请求的功能。例如:
|
在这个例子中,如果fetchSomething
在 3 秒内完成,Promise.race
会返回该请求的结果,否则delay
会在 3 秒后拒绝,导致Promise.race
被拒绝,这样就实现了请求的超时控制。