获取 API、自定义请求标头、CORS 和跨域重定向 [英] Fetch API, custom request headers, CORS, and cross-origin redirects
问题描述
我需要在浏览器中使用自定义请求标头发出 HTTP GET 请求,并在结果流入时对其进行处理.Fetch API 非常适合:
I need to make an HTTP GET request with custom request headers in-browser and process the result as it streams in. The Fetch API is ideal for this:
fetch('https://example.com/resource', {
method: 'GET',
headers: {
'X-Brad-Test': 'true'
},
cache: 'no-store',
mode: 'cors'
}).then((res) => {
const reader = res.body.getReader();
// etc.
});
这很好用.由于存在自定义标头,因此浏览器会使用 OPTIONS 请求将请求预先发送到 /resource
.我已将服务器配置为使用 204 No Content
和以下标头进行响应:
This works quite well. Since there are custom headers, the browser pre-flights the request with an OPTIONS request to /resource
. I have configured my server to respond with a 204 No Content
and the following headers:
Access-Control-Allow-Headers: X-Requested-With, Range, If-Range, X-Brad-Test
Access-Control-Allow-Origin: *
浏览器对此感到满意,然后发出 GET 请求,服务器返回带有数据的 200 OK
,浏览器允许我访问响应头和正文.
The browser is happy with this, then makes a GET request, the server returns a 200 OK
with the data, and the browser allows me to access the response headers and body.
当有重定向时问题就来了.OPTIONS
请求成功,并带有 204 No Content
和与以前相同的标头.浏览器发出正确的 GET
请求,并在服务器上发送带有 Location:
标头的 302
.Chrome 抛出以下错误:
The problem comes in when there is a redirect. The OPTIONS
request succeeds with the 204 No Content
and the same headers as before. The browser makes the correct GET
request, and on the server I send a 302
with a Location:
header. Chrome throws the following error:
Fetch API 无法加载 https://example.com/resource.从 'https://example.com/resource' 重定向到 'http://some-other-origin/resource' 已被 CORS 策略阻止:请求需要预检,不允许进行跨域重定向.
Fetch API cannot load https://example.com/resource. Redirect from 'https://example.com/resource' to 'http://some-other-origin/resource' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.
这是出乎意料的,对我来说似乎很荒谬.我希望浏览器遵循重定向,并为这个新位置发出另一个飞行前请求,但它没有这样做.
This was unexpected, and seems nonsensical to me. I expected the browser to follow the redirect, and do another pre-flight request for this new location, but it didn't do that.
更奇怪的是我可以绕过这个客户端.我可以在没有自定义标头的情况下发出 HTTP 请求,通过查看 Response 对象找出重定向后最终到达的位置,然后使用我的自定义标头在新目标处发出第二个请求.当然,这并非在所有情况下都有效,我宁愿不依赖这个 hack.我宁愿找到合适的方法.
Stranger still is that I can sort of hack around this client-side. I can make an HTTP request without my custom header, figure out where I ended up after redirects by looking at the Response object, then make a second request at the new target with my custom headers. This doesn't work in all cases of course, and I'd rather not rely on this hack. I'd rather find a proper way.
两个问题:
- 允许客户端跟踪重定向的正确方法是什么?我可以使用某种
Access-Control-*
标头吗? - 为什么会有这个限制?不关注并在关注的 URL 上运行 pre-flight 可以防止哪些安全问题?
推荐答案
支持重定向到需要预检的请求是对 Fetch(定义 CORS)的最新更改.
Supporting redirects to requests that require a preflight is very recent change to Fetch (which defines CORS).
https://github.com/whatwg/fetch/commit/0d9a4db8bc02251cc9e391543bb3c1322fb882f2
我相信一些实施已经开始调整他们的实施,但这需要一些时间才能接触到每个人.
I believe some implementations have started adjusting their implementations, but this will take some time to reach everyone.
这篇关于获取 API、自定义请求标头、CORS 和跨域重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!