简体   繁体   English

发出多个 Axios 请求导致 CORS 错误

[英]Making multiple Axios requests causing CORS errors

I have a HTTP POST request I'm making from the frontend using Axios to the Firebase Functions backend.我有一个 HTTP POST 请求,我使用Axios从前端向 Firebase 功能后端发出请求。 I want to be able to send two requests at the same time to call two functions, createEmaileList and zohoCrmHook .我希望能够同时发送两个请求来调用两个函数createEmaileListzohoCrmHook The problem is, when I make a request to both functions at the same time, it gives me the CORS error.问题是,当我同时向两个函数发出请求时,它给了我 CORS 错误。 When I make a request to individual function, they work perfectly fine.当我向个人 function 提出请求时,它们工作得很好。 How do I make a request to multiple functions at the same time?如何同时向多个函数发出请求?

Following is the frontend:以下是前端:

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));
}

The backend index.js is as follows:后端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)

I've imported the cors module and implemented the function as following, but it still only works individually and not both at the same time我已经导入了cors模块并实现了 function 如下,但它仍然只能单独工作,不能同时工作

createEmailList.js 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 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' })
        }
    })
}

Update更新
I've also tried combining the two Firebase Functions into one as following:我还尝试将两个 Firebase 函数合并为一个,如下所示:

exports.myWebHook = functions.https.onRequest(async (req, res) => {
  createEmailList(req, res)
  zohoCrmHook(req, res)
})

and converting the frontend axios request into one:并将前端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));
    }

But, it still gives the same CORS error:但是,它仍然给出相同的 CORS 错误:

Access to XMLHttpRequest at ' https://us-landing-page.cloudfunctions.net/myWebHook ' from origin ' https://www.website.com ' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request. Access to XMLHttpRequest at ' https://us-landing-page.cloudfunctions.net/myWebHook ' from origin ' https://www.website.com ' has been blocked by CORS policy: Response to preflight request doesn't pass access控制检查:预检请求不允许重定向。

Update2更新2
I've tried to incorporating the CORS module in index.js as following and removed the CORS module from both of the functions.我尝试将 CORS 模块合并到index.js中,如下所示,并从这两个函数中删除了 CORS 模块。

exports.myWebHook = functions.https.onRequest((req, res) => {
  cors(req, res, async () => {            
    zohoCrmHook(req, res)  
    createEmailList(req, res)
  })
})

Now, the axios request to the server doesn't incur any CORS errors and the myWebHook function gets invoked with no issues, but the neither of zohoCrmHook nor createEmailList function gets invoked. Now, the axios request to the server doesn't incur any CORS errors and the myWebHook function gets invoked with no issues, but the neither of zohoCrmHook nor createEmailList function gets invoked.

If we look at the code we see that CORS in not only imported but also invoked with an options object.如果我们查看代码,我们会看到 CORS 不仅导入,而且还使用选项 object 调用。 So I think it is instantiating CORS twice and setting multiple times the same CORS headers, which is known to cause issues.所以我认为它两次实例化 CORS 并多次设置相同的 CORS 标头,这会导致问题。

const cors = require('cors')({ origin: true })

My suggestion is, to instantiate CORS once in the entry point and add the functions as resources to the same CORS instance.我的建议是,在入口点实例化 CORS 一次,并将函数作为资源添加到同一个 CORS 实例中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM