Выполнение нескольких запросов Axios, вызывающих ошибки CORS - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть HTTP-запрос POST, который я делаю из внешнего интерфейса, используя Axios, для внутреннего интерфейса Firebase Functions. Я хочу иметь возможность отправлять два запроса одновременно для вызова двух функций, 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. cloudfunctions.net/myWebHook 'from origin' https://www.website.com' заблокирован политикой CORS: Ответ на запрос предварительной проверки не проходит проверку контроля доступа: Перенаправление не разрешено для запроса предварительной проверки.

Обновление2
Я пытался включить CORS mвведите 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.

1 Ответ

1 голос
/ 07 ноября 2019

Если мы посмотрим на код, то увидим, что CORS не только импортируется, но и вызывается с объектом параметров. Поэтому я думаю, что это создание экземпляра CORS дважды и многократная установка одинаковых заголовков CORS, что, как известно, вызывает проблемы.

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

Я предлагаю создать экземпляр CORS один раз в точке входа и добавить функции какресурсы для того же экземпляра CORS.

...