Cloud Functions for Firebase 在 CORS 预检请求上触发功能
Posted
技术标签:
【中文标题】Cloud Functions for Firebase 在 CORS 预检请求上触发功能【英文标题】:Cloud Functions for Firebase triggering function on CORS preflight request 【发布时间】:2018-03-04 08:09:19 【问题描述】:我有一个云功能,可以验证客户端上表单提交的输入。我正在使用 Cloud Functions for Firebase https triggers 和 cors express middleware。
Firebase 函数
const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors')(origin: true);
const validateImageForm = require('./library/validate-image-form');
exports.apiValidateImageForm = functions.https.onRequest((req, res) =>
cors(req, res, () =>
validateImageForm(req.body.formInputs, req.body.imageStatus).then((data) =>
res.status(200).send(data);
);
);
);
客户端调用函数
const validateImageFormFetchOptions =
headers:
'Accept': 'application/json',
'Content-Type': 'application/json'
,
method: 'POST',
body: JSON.stringify(
formInputs: formInputs
)
fetch('https://project-url.cloudfunctions.net/apiValidateImageForm', validateImageFormFetchOptions)
.then(response => response.json())
.then(serverErrors => console.log(serverErrors));
问题
当我使用提取请求从客户端调用此函数时,我在函数日志中看到两个 apiValidateImageForm 触发器。第一个是状态 204,我假设这来自检查来源的 cors 预检请求。最后的请求是状态 200。我只想要一个函数触发器,当我获取 apiValidateImageForm 函数时。我担心随着时间的推移,输出状态 204 的预检请求会将不必要的函数调用添加到我的项目配额中。
问题
是否可以防止 firebase 在预检请求中触发函数调用?如果没有,那么有没有办法阻止预检请求并成功地将数据传递给函数。
【问题讨论】:
只要您在请求中添加Content-Type': 'application/json'
标头,浏览器就会在尝试来自您的代码的请求之前自动执行 CORS preflight OPTIONS 请求。因此,唯一避免的方法是不将其编码为 application/json 发送,而是将 JSON 作为请求正文中的参数值发送,内容类型为 application/x-www-form-urlencoded;也就是说,就像json=[your JSON data here]
这样的名称+值对。请参阅***.com/a/43881141/441757 答案的如何避免 CORS 预检部分
【参考方案1】:
要修复重复的请求 200 和 204,然后更改客户端获取请求的方式。 @sideshowbarker 是对的。浏览器会自动执行 CORS 预检 OPTIONS 请求,因此这在 Cloud Functions for Firebase 中不是问题。 This answer 很有帮助。
为了修复预检,我将代码更改为以下内容:
客户端调用函数
完全从 fetch 选项中删除了标头,而不是将内容类型设置为 application/json。默认情况下,获取请求的内容类型是 application/x-www-form-urlencoded;字符集=UTF-8。
const validateImageFormFetchOptions =
method: 'POST',
body: JSON.stringify(
formInputs: formInputs
)
fetch('https://project-url.cloudfunctions.net/apiValidateImageForm', validateImageFormFetchOptions)
.then(response => response.json())
.then(serverErrors => console.log(serverErrors));
Firebase 函数
显式解析请求正文,因为它现在作为文本字符串接收。
const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors')(origin: true);
const validateImageForm = require('./library/validate-image-form');
exports.apiValidateImageForm = functions.https.onRequest((req, res) =>
cors(req, res, () =>
const body = JSON.parse(req.body);
validateImageForm(body.formInputs, body.imageStatus).then((data) =>
res.status(200).send(data);
);
);
);
【讨论】:
以上是关于Cloud Functions for Firebase 在 CORS 预检请求上触发功能的主要内容,如果未能解决你的问题,请参考以下文章