当使用 headers 发送 POST 请求时,Firebase HTTP 函数触发两次
Firebase HTTP Function triggered twice when POST request sent with headers
我部署了 firebase HTTP cloud function 并且遇到了这种(意外)行为:
- 当我使用
fetch()
从浏览器环境调用该函数(使用 POST)时,该函数被触发两次,一次没有在 body 中发送任何数据,并且如我所料的另一次。在前端(chrome 网络选项卡)我只能看到 1 个请求,成功的请求。
- 这只会发生在 POST 个请求中
- 这只会在发送请求时发生 headers
这是我不理解的正常行为还是潜在的错误?
我的最小云函数
exports.run = functions.https.onRequest(async (req, res) => {
// ALLOW CORS FOR POST REQUEST:
// =>
res.set('Access-Control-Allow-Origin', '*');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
return res.status(200).send({
status: "ok",
body: req.body,
query: req.query,
}).end();
});
从前端调用
// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };
// GET request => ✅ works as expected
fetch(url);
// POST request without headers => ✅ works as expected
fetch(url, {
method: 'POST',
body: JSON.stringify(postData),
});
// POST request with headers => ❌ 2 requests get triggered
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData),
});
此行为的发生是因为 CORS preflight request:
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers.
...
A preflight request is automatically issued by a browser, and in normal cases, front-end developers don't need to craft such requests themselves. It appears when a request is qualified as "to be preflighted" and omitted for simple requests.
正如另一个 question 中所指出的:
As long as you’re adding a Content-Type': 'application/json'
header to the request, the browser is going to automatically on its own do a CORS preflight OPTIONS request before trying the request from your code.
因此,这是正常行为,不是 Cloud Functions for Firebase 的问题。
为了没有这两个请求,您可以按照此 answer:
的建议更改 header 请求
// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };
// POST request with different header => ✅ only one request is triggered
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: JSON.stringify(postData),
}).then(data => console.log(data));
我部署了 firebase HTTP cloud function 并且遇到了这种(意外)行为:
- 当我使用
fetch()
从浏览器环境调用该函数(使用 POST)时,该函数被触发两次,一次没有在 body 中发送任何数据,并且如我所料的另一次。在前端(chrome 网络选项卡)我只能看到 1 个请求,成功的请求。 - 这只会发生在 POST 个请求中
- 这只会在发送请求时发生 headers
这是我不理解的正常行为还是潜在的错误?
我的最小云函数
exports.run = functions.https.onRequest(async (req, res) => {
// ALLOW CORS FOR POST REQUEST:
// =>
res.set('Access-Control-Allow-Origin', '*');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
return res.status(200).send({
status: "ok",
body: req.body,
query: req.query,
}).end();
});
从前端调用
// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };
// GET request => ✅ works as expected
fetch(url);
// POST request without headers => ✅ works as expected
fetch(url, {
method: 'POST',
body: JSON.stringify(postData),
});
// POST request with headers => ❌ 2 requests get triggered
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData),
});
此行为的发生是因为 CORS preflight request:
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. ... A preflight request is automatically issued by a browser, and in normal cases, front-end developers don't need to craft such requests themselves. It appears when a request is qualified as "to be preflighted" and omitted for simple requests.
正如另一个 question 中所指出的:
As long as you’re adding a
Content-Type': 'application/json'
header to the request, the browser is going to automatically on its own do a CORS preflight OPTIONS request before trying the request from your code.
因此,这是正常行为,不是 Cloud Functions for Firebase 的问题。
为了没有这两个请求,您可以按照此 answer:
的建议更改 header 请求// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };
// POST request with different header => ✅ only one request is triggered
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: JSON.stringify(postData),
}).then(data => console.log(data));