【发布时间】:2020-03-04 09:38:24
【问题描述】:
我使用 Axios 从前端向 Firebase Functions 后端发出 HTTP POST 请求。我希望能够同时发送两个请求来调用两个函数,createEmaileList 和zohoCrmHook。问题是,当我同时向这两个函数发出请求时,它给了我 CORS 错误。当我向单个功能提出请求时,它们工作得很好。如何同时向多个函数发出请求?
下面是前端:
const handleSubmit = e => {
setLoading(true)
e.preventDefault()
axios.all([
axios.post(`${ROOT_URL}/createEmailList`, {
email,
firstName,
lastName
}),
axios.post(`${ROOT_URL}/zohoCrmHook`, {
email,
firstName,
lastName
})
])
.then(axios.spread((emailRes, crmRes) => {
if(emailRes.status===200 || emailRes.status===204 || crmRes.status===200 || crmRes.status===204 || crmRes.status===201){
setLoading(false)
closeModal()
}
}))
.catch(err=> console.log(err));
}
后台index.js如下:
const functions = require('firebase-functions');
const admin = require("firebase-admin")
const serviceAccount = require("./service_account.json");
const createEmailList = require('./createEmailList')
const zohoCrmHook = require('./zohoCrmHook')
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://landing-page.firebaseio.com"
})
exports.zohoCrmHook = functions.https.onRequest(zohoCrmHook)
exports.createEmailList = functions.https.onRequest(createEmailList)
我已经导入了cors 模块并实现了如下功能,但它仍然只能单独工作,不能同时工作
createEmailList.js
const admin = require('firebase-admin')
const cors = require('cors')({ origin: true })
module.exports = (req, res) => {
cors(req, res, () => {
if (!req.body.email) {
return res.status(422).send({ error: 'Bad Input'})
}
const email = String(req.body.email)
const firstName = String(req.body.firstName)
const lastName = String(req.body.lastName)
const data = {
email,
firstName,
lastName
}
const db = admin.firestore()
const docRef = db.collection('users')
.doc(email)
.set(data, { merge: false })
.catch(err => res.status(422).send({ error: err }))
return res.status(204).end();
})
}
zohoCrmHook.js
const axios = require('axios');
const functions = require('firebase-functions');
const cors = require('cors')({ origin: true })
// zoho
const clientId = functions.config().zoho.client_id;
const clientSecret = functions.config().zoho.client_secret;
const refreshToken = functions.config().zoho.refresh_token;
const baseURL = 'https://accounts.zoho.com';
module.exports = (req, res) => {
cors(req, res, async () => {
const newLead = {
'data': [
{
'Email': String(req.body.email),
'Last_Name': String(req.body.lastName),
'First_Name': String(req.body.firstName),
}
],
'trigger': [
'approval',
'workflow',
'blueprint'
]
};
const { data } = await getAccessToken();
const accessToken = data.access_token;
const leads = await getLeads(accessToken);
const result = checkLeads(leads.data.data, newLead.data[0].Email);
if (result.length < 1) {
try {
return res.json(await createLead(accessToken, newLead));
} catch (e) {
console.log("createLead error", e);
}
} else {
return res.json({ message: 'Lead already in CRM' })
}
})
}
更新
我还尝试将这两个 Firebase 函数合二为一,如下所示:
exports.myWebHook = functions.https.onRequest(async (req, res) => {
createEmailList(req, res)
zohoCrmHook(req, res)
})
并将前端axios 请求合二为一:
const handleSubmit = e => {
setLoading(true)
e.preventDefault()
axios.post(`${ROOT_URL}/myWebHook`, {
email,
firstName,
lastName
})
.then(res => {
if(res.status===200 || res.status===204){
setLoading(false)
closeModal()
}
})
.catch(err=> console.log(err));
}
但是,它仍然给出相同的 CORS 错误:
访问 XMLHttpRequest 在 'https://us-landing-page.cloudfunctions.net/myWebHook' 来自原点 'https://www.website.com' 已被 CORS 阻止 策略:对预检请求的响应未通过访问控制 检查:预检请求不允许重定向。
更新2
我尝试将 CORS 模块合并到 index.js 中,如下所示,并从这两个函数中删除了 CORS 模块。
exports.myWebHook = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
zohoCrmHook(req, res)
createEmailList(req, res)
})
})
现在,对服务器的axios 请求不会引发任何CORS 错误,并且myWebHook 函数被调用没有问题,但zohoCrmHook 和createEmailList 函数都没有被调用。
【问题讨论】:
-
实际上不知道 Firebase,但两次导入 CORS 并设置其值看起来很可疑。我觉得 CORS 应该初始化一次,然后只添加资源。我知道在堆栈中设置多个 CORS 标头会引发错误的问题。不确定这里是否正是这种情况,但可能值得一试。
-
如果我要从任何一个函数中删除 CORS 模块,则表明进程已被 CORS 策略阻止的错误只是指向该特定函数。
-
听起来更好,您可以不在入口点设置 cors 并导入您的函数并将它们作为资源添加到同一个 cors 实例吗?
-
我已经尝试了你的建议并通过答案更新了,但仍然不行
-
当我尝试应用 CORS 模块的不同变体时,我也曾一度收到错误消息,指出已声明的 Header 无法再次声明。当时不知道那是什么意思,但是,看了你的回答,我现在明白了。
标签: javascript node.js firebase cors axios