我在做
console.log("navigating");
var rsp = await fetch(params.url, {
credentials: "include", redirect: "manual", mode: "cors"
});
console.log(rsp);
rsp.headers.forEach(console.log);
console.log(rsp.headers.get('Location'));
console.log(rsp.headers.get('location'));
以及来自 chrome 开发工具的响应标头:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:4400
Access-Control-Expose-Headers: Location
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 0
Date: Fri, 05 Oct 2018 12:48:21 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: http://localhost/test
给予
Response
body: (...)
bodyUsed: falseheaders:
Headers {}
ok: false
redirected: false
status: 0
statusText: ""
type: "opaqueredirect"
url: "..."
index.ts:161 null
index.ts:162 null
是否无法在重定向响应中获取响应标头?
是否无法在重定向响应中获取响应标头?
不,这是不可能的。 Fetch 规范中的要求阻止了它。
问题显示的是
manual
重定向模式的预期内容:暴露给前端JS的标头对象在响应redirect: "manual"
请求时预计为空。
当请求设置
manual
重定向模式时,响应类型为opaqueredirect
。有关其影响的信息位于 https://developer.mozilla.org/en-US/docs/Web/API/Response/type:
:使用opaqueredirect
发出获取请求。响应的状态为 0,headers 为空,body 为 null,trailer 为空。redirect: "manual"
MDN 文章中的这些详细信息直接基于 Fetch 规范的以下部分:
https://fetch.spec.whatwg.org/#concept-request-redirect-mode
请求具有关联的重定向模式,即
、"follow"
或"error"
。"manual"
……
“手动”:当请求遇到重定向时检索不透明重定向过滤响应,以便可以手动遵循重定向。
https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect
opaque-redirect过滤响应是一个过滤响应,其类型为
,状态为"opaqueredirect"
,状态消息为空字节序列,头列表为空,正文为空0
……
不透明过滤响应和不透明重定向过滤响应与网络错误几乎无法区分
这是一个老问题,但我认为答案可以扩展,并且可以帮助某人节省一些时间。
基本上值得指出的是,fetch() 在浏览器环境和 NodeJS 等后端环境中的行为不同(因为没有 CORS 机制)。
redirect: 'manual'
在浏览器中: 总会给你“opaqueredirect”,这是一个空的响应。因此,无论如何,都不可能在第一个 URL 处停止并从浏览器中的标头中获取重定向 URL。
在 NodeJS 中: 它将在重定向处停止,并会给您完整的响应。可以说,在后端,它的工作原理正如许多人所期望的那样。
因此,如果您正在开发一个完整的堆栈应用程序,并且只想从外部 API 获取重定向URL - 只需将负责它的代码移至您的后端即可。
我在 NodeJS 中的代码示例:
fetch('https://api.example/php/search.php?X=78994&Y=158&date=20240509', {
method: 'HEAD',
redirect: 'manual'
})
.then(response => {
if (response.status >= 300 && response.status < 400) {
console.log('Redirect status:', response.status);
console.log('Redirect location:', response.headers.get('location'));
} else {
console.log('Response status:', response.status);
console.log('Response did not redirect:', response);
}
})
.catch(error => {
console.error('Error during fetch:', error);
});
日志:
Redirect status: 301
Redirect location: ./new_page.php?date=20240509¶m1=324¶m2=43242