发出多个 Axios 请求导致 CORS 错误
Posted
技术标签:
【中文标题】发出多个 Axios 请求导致 CORS 错误【英文标题】:Making multiple Axios requests causing CORS errors 【发布时间】: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 无法再次声明。当时不知道那是什么意思,但是,看了你的回答,我现在明白了。 【参考方案1】:如果我们查看代码,我们会看到 CORS 不仅被导入,而且还被选项对象调用。所以我认为它两次实例化 CORS 并多次设置相同的 CORS 标头,这会导致问题。
const cors = require('cors')( origin: true )
我的建议是,在入口点实例化一次 CORS,并将函数作为资源添加到同一个 CORS 实例。
【讨论】:
以上是关于发出多个 Axios 请求导致 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章
在 Django 中使用 Axios 和 CORS 获取 POST 请求的错误请求并做出反应