pre-flight 请求如何在没有响应的情况下收到 headers?
How does a pre-flight request receive headers without having a response?
我一直在阅读有关 CORS 和 pre-flight 请求,并且已经理解基本上它是一种 OPTIONS
请求,如果服务器允许,则在发出实际请求之前发送然后再次发送实际请求。但最让我困惑的是,浏览器如何能够在没有收到来自服务器的实际响应的情况下接收响应 headers? headers 是否发送无论是否已发送响应??就像下面的 nodejs
代码片段一样,您可以看到我创建了一个 middleware
接收 OPTIONS
请求并响应发送实际请求所需的 headers。一旦在相同的 login
路由上得到验证,浏览器就会发送实际请求。但是您一定已经注意到我没有从 handler[=42] 发送 response =] 的 OPTIONS 中间件函数 我只发送 headers。那这一切还怎么办? headers 如何在没有响应的情况下发送到浏览器?
app.options("/login", (req, resp, next) => {
resp.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
resp.header("Access-Control-Allow-Methods", "GET, POST, PUT");
resp.header("Access-Control-Allow-Headers", "Content-type");
next();
});
app.post("/login", (req, resp) => {
resp.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
resp.header("Access-Control-Allow-Methods", "GET, POST, PUT");
resp.header("Access-Control-Allow-Headers", "Content-type");
resp.json({
msg:"Sucess"
});
});
要回答这个问题,您需要查看 express 源代码。在 router\index.js 中(最终将在您从处理程序调用 next()
后执行),您会发现以下代码:
// for options requests, respond with a default if nothing else responds
if (req.method === 'OPTIONS') {
done = wrap(done, function(old, err) {
if (err || options.length === 0) return old(err);
sendOptionsResponse(res, options, old);
});
}
在您的情况下,if 条件为假,因为您没有在您的处理程序中响应,导致调用 sendOptionsResponse
,其定义如下:
// send an OPTIONS response
function sendOptionsResponse(res, options, next) {
try {
var body = options.join(',');
res.set('Allow', body);
res.send(body);
} catch (err) {
next(err);
}
}
这就是为什么实际上会发送响应,即使您没有明确地从您的处理程序发送响应。
顺便说一句:您可能想看一下 cors-package,这对促进 cors-setup 有很大帮助。
我一直在阅读有关 CORS 和 pre-flight 请求,并且已经理解基本上它是一种 OPTIONS
请求,如果服务器允许,则在发出实际请求之前发送然后再次发送实际请求。但最让我困惑的是,浏览器如何能够在没有收到来自服务器的实际响应的情况下接收响应 headers? headers 是否发送无论是否已发送响应??就像下面的 nodejs
代码片段一样,您可以看到我创建了一个 middleware
接收 OPTIONS
请求并响应发送实际请求所需的 headers。一旦在相同的 login
路由上得到验证,浏览器就会发送实际请求。但是您一定已经注意到我没有从 handler[=42] 发送 response =] 的 OPTIONS 中间件函数 我只发送 headers。那这一切还怎么办? headers 如何在没有响应的情况下发送到浏览器?
app.options("/login", (req, resp, next) => {
resp.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
resp.header("Access-Control-Allow-Methods", "GET, POST, PUT");
resp.header("Access-Control-Allow-Headers", "Content-type");
next();
});
app.post("/login", (req, resp) => {
resp.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
resp.header("Access-Control-Allow-Methods", "GET, POST, PUT");
resp.header("Access-Control-Allow-Headers", "Content-type");
resp.json({
msg:"Sucess"
});
});
要回答这个问题,您需要查看 express 源代码。在 router\index.js 中(最终将在您从处理程序调用 next()
后执行),您会发现以下代码:
// for options requests, respond with a default if nothing else responds
if (req.method === 'OPTIONS') {
done = wrap(done, function(old, err) {
if (err || options.length === 0) return old(err);
sendOptionsResponse(res, options, old);
});
}
在您的情况下,if 条件为假,因为您没有在您的处理程序中响应,导致调用 sendOptionsResponse
,其定义如下:
// send an OPTIONS response
function sendOptionsResponse(res, options, next) {
try {
var body = options.join(',');
res.set('Allow', body);
res.send(body);
} catch (err) {
next(err);
}
}
这就是为什么实际上会发送响应,即使您没有明确地从您的处理程序发送响应。
顺便说一句:您可能想看一下 cors-package,这对促进 cors-setup 有很大帮助。