到目前为止,我们已经对 fetch
有了相当多的了解。
让我们看看 API 的其余部分,以涵盖它的所有功能。
请注意:这些选项中的大多数很少使用。您可以跳过本章,仍然可以很好地使用 fetch
。
不过,了解 fetch
的功能还是很好的,这样如果需要,您可以返回并阅读详细信息。
以下是所有可能的 fetch
选项及其默认值(注释中的替代方案)的完整列表
let promise = fetch(url, {
method: "GET", // POST, PUT, DELETE, etc.
headers: {
// the content type header value is usually auto-set
// depending on the request body
"Content-Type": "text/plain;charset=UTF-8"
},
body: undefined, // string, FormData, Blob, BufferSource, or URLSearchParams
referrer: "about:client", // or "" to send no Referer header,
// or an url from the current origin
referrerPolicy: "strict-origin-when-cross-origin", // no-referrer-when-downgrade, no-referrer, origin, same-origin...
mode: "cors", // same-origin, no-cors
credentials: "same-origin", // omit, include
cache: "default", // no-store, reload, no-cache, force-cache, or only-if-cached
redirect: "follow", // manual, error
integrity: "", // a hash, like "sha256-abcdef1234567890"
keepalive: false, // true
signal: undefined, // AbortController to abort request
window: window // null
});
令人印象深刻的列表,对吧?
我们在 Fetch 一章中完全涵盖了 method
、headers
和 body
。
signal
选项在 Fetch: Abort 中介绍。
现在让我们探索剩余的功能。
referrer,referrerPolicy
这些选项控制 fetch
如何设置 HTTP Referer
头。
通常,该头会自动设置,并包含发出请求的页面的 URL。在大多数情况下,它根本不重要,有时,出于安全目的,有必要删除或缩短它。
referrer
选项允许设置任何 Referer
(在当前域内)或将其删除。
要发送无引用来源,请设置一个空字符串。
fetch('/page', {
referrer: "" // no Referer header
});
要设置当前域内的另一个 URL。
fetch('/page', {
// assuming we're on https://javascript.js.cn
// we can set any Referer header, but only within the current origin
referrer: "https://javascript.js.cn/anotherpage"
});
referrerPolicy
选项为 Referer
设置通用规则。
请求分为 3 种类型。
- 对同一域的请求。
- 对另一个域的请求。
- 从 HTTPS 到 HTTP 的请求(从安全协议到不安全协议)。
与允许设置精确 Referer
值的 referrer
选项不同,referrerPolicy
为每种请求类型告诉浏览器通用规则。
可能的取值在 Referrer Policy 规范 中描述。
"strict-origin-when-cross-origin"
– 默认值:对于同一域,发送完整的Referer
;对于跨域,仅发送域,除非它是 HTTPS→HTTP 请求,则不发送任何内容。"no-referrer-when-downgrade"
– 始终发送完整的Referer
,除非我们从 HTTPS 发送请求到 HTTP(到安全性较低的协议)。"no-referrer"
– 从不发送Referer
。"origin"
– 仅在Referer
中发送域,而不是完整的页面 URL,例如,仅发送http://site.com
而不是http://site.com/path
。"origin-when-cross-origin"
– 对同一域发送完整的Referer
,但对于跨域请求仅发送域部分(如上所述)。"same-origin"
– 对同一域发送完整的Referer
,但对于跨域请求不发送Referer
。"strict-origin"
– 仅发送域,对于 HTTPS→HTTP 请求不发送Referer
。"unsafe-url"
– 始终在Referer
中发送完整的 URL,即使对于 HTTPS→HTTP 请求也是如此。
以下表格列出了所有组合。
值 | 对同一域 | 对另一个域 | HTTPS→HTTP |
---|---|---|---|
"no-referrer" |
- | - | - |
"no-referrer-when-downgrade" |
完整 | 完整 | - |
"origin" |
域 | 域 | 域 |
"origin-when-cross-origin" |
完整 | 域 | 域 |
"same-origin" |
完整 | - | - |
"strict-origin" |
域 | 域 | - |
"strict-origin-when-cross-origin" 或 "" (默认) |
完整 | 域 | - |
"unsafe-url" |
完整 | 完整 | 完整 |
假设我们有一个管理区域,其 URL 结构不应从网站外部得知。
如果我们发送 fetch
,则默认情况下,它始终会发送带有我们页面完整 URL 的 Referer
标头(除非我们从 HTTPS 请求到 HTTP,则不发送 Referer
)。
例如,Referer: https://javascript.js.cn/admin/secret/paths
。
如果我们希望其他网站只知道域部分,而不是 URL 路径,我们可以设置以下选项。
fetch('https://another.com/page', {
// ...
referrerPolicy: "origin-when-cross-origin" // Referer: https://javascript.js.cn
});
我们可以将其添加到所有 fetch
调用中,也许可以将其集成到我们项目的 JavaScript 库中,该库执行所有请求并在内部使用 fetch
。
与默认行为唯一的区别是,对于跨域请求,fetch
只发送 URL 的 origin 部分(例如 https://javascript.js.cn
,不包含路径)。对于同源请求,我们仍然会获得完整的 Referer
(可能对调试有用)。
fetch
Referrer 策略,在 规范 中描述,不仅仅适用于 fetch
,而是更全局的。
特别是,可以使用 Referrer-Policy
HTTP 头部为整个页面设置默认策略,或者使用 <a rel="noreferrer">
为每个链接设置策略。
模式
mode
选项是一种安全措施,可以防止偶尔发生的跨域请求
"cors"
– 默认值,允许跨域请求,如 Fetch:跨域请求 中所述,"same-origin"
– 禁止跨域请求,"no-cors"
– 只允许安全的跨域请求。
当 fetch
的 URL 来自第三方,并且我们想要一个“断电开关”来限制跨域功能时,此选项可能很有用。
凭据
credentials
选项指定 fetch
是否应该将 cookie 和 HTTP-Authorization 头部与请求一起发送。
"same-origin"
– 默认值,不发送跨域请求,"include"
– 始终发送,需要跨域服务器的Access-Control-Allow-Credentials
,以便 JavaScript 访问响应,这在 Fetch:跨域请求 一章中介绍过,"omit"
– 从不发送,即使对于同源请求也是如此。
缓存
默认情况下,fetch
请求使用标准的 HTTP 缓存。也就是说,它尊重 Expires
和 Cache-Control
头部,发送 If-Modified-Since
等等。就像常规的 HTTP 请求一样。
cache
选项允许忽略 HTTP 缓存或微调其使用方式
"default"
–fetch
使用标准的 HTTP 缓存规则和头部,"no-store"
– 完全忽略 HTTP 缓存,如果我们设置If-Modified-Since
、If-None-Match
、If-Unmodified-Since
、If-Match
或If-Range
头部,此模式将成为默认模式,"reload"
– 不从 HTTP 缓存(如果有)中获取结果,但使用响应填充缓存(如果响应头部允许此操作),"no-cache"
– 如果存在缓存响应,则创建条件请求,否则创建普通请求。使用响应填充 HTTP 缓存,"force-cache"
– 使用来自 HTTP 缓存的响应,即使它已过期。如果 HTTP 缓存中没有响应,则进行常规的 HTTP 请求,正常执行,"only-if-cached"
– 使用来自 HTTP 缓存的响应,即使它已过期。如果 HTTP 缓存中没有响应,则会报错。仅在mode
为"same-origin"
时有效。
重定向
通常,fetch
会透明地遵循 HTTP 重定向,例如 301、302 等。
redirect
选项允许更改此行为。
"follow"
– 默认值,遵循 HTTP 重定向。"error"
– 在发生 HTTP 重定向时报错。"manual"
– 允许手动处理 HTTP 重定向。在发生重定向的情况下,我们将获得一个特殊的响应对象,其中response.type="opaqueredirect"
且状态和其他大多数属性为零或为空。
完整性
integrity
选项允许检查响应是否与预先知道的校验和匹配。
如 规范 中所述,支持的哈希函数为 SHA-256、SHA-384 和 SHA-512,根据浏览器可能还有其他函数。
例如,我们正在下载一个文件,并且知道它的 SHA-256 校验和为“abcdef”(当然,实际的校验和更长)。
我们可以将其放在 integrity
选项中,如下所示
fetch('http://site.com/file', {
integrity: 'sha256-abcdef'
});
然后 fetch
将自行计算 SHA-256 并将其与我们的字符串进行比较。如果发生不匹配,则会触发错误。
保持活动
keepalive
选项表示请求可能“超出”发起它的网页的生命周期。
例如,我们收集有关当前访问者如何使用我们页面的统计信息(鼠标点击、他查看的页面片段),以分析和改进用户体验。
当访问者离开我们的页面时,我们希望将数据保存到我们的服务器。
我们可以使用 window.onunload
事件来实现这一点。
window.onunload = function() {
fetch('/analytics', {
method: 'POST',
body: "statistics",
keepalive: true
});
};
通常,当文档卸载时,所有关联的网络请求都会被中止。但是 keepalive
选项告诉浏览器即使在离开页面后也要在后台执行请求。因此,此选项对于我们的请求成功至关重要。
它有一些限制。
- 我们不能发送兆字节:
keepalive
请求的正文限制为 64KB。- 如果我们需要收集大量有关访问的统计信息,我们应该定期以数据包的形式将其发送出去,这样最后一次
onunload
请求就不会剩下太多数据。 - 此限制适用于所有
keepalive
请求。换句话说,我们可以并行执行多个keepalive
请求,但它们的正文长度总和不应超过 64KB。
- 如果我们需要收集大量有关访问的统计信息,我们应该定期以数据包的形式将其发送出去,这样最后一次
- 如果文档已卸载,我们无法处理服务器响应。因此,在我们的示例中,
fetch
将由于keepalive
而成功,但后续函数将无法工作。- 在大多数情况下,例如发送统计信息,这不是问题,因为服务器只是接受数据,通常会向此类请求发送空响应。
评论
<code>
标签,对于多行代码,请使用<pre>
标签,对于超过10行的代码,请使用沙盒(plnkr,jsbin,codepen…)