Vue.js + Axios (serverless) как избежать CORS error при обращении к YooKassa?
Разрабатываю одностраничный сайт на Vue.js + Strapi. Frontend базируется на Firebase, Strapi установлен на HerokuApp. Все данные из админки получаю и передаю (как с localhost:8080, так и с боевого домена, делегированного на Firebase) без проблем через асинхронные методы вида:
await axios.get( 'https://desolate-mesa-XXXXX.herokuapp.com/infoblock' )
.then( response => ( this.infoblock= response.data )
)
Но возникла проблема, когда потребовалось подключить YooKassa (она же ЮКасса, она же Яндекс.Касса). По попытке создать платеж возникает сообщение:
Access to XMLHttpRequest at 'https://api.yookassa.ru/v3/payments' from origin 'https://domain.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Это проблема решается, и платеж успешно оформляется, если использовать devServer proxy на Vue.js, но это работает только на машине разработчика, разумеется.
Подскажите, как лучше поступить? Есть вариант обойтись без установки Express или подобных backend-фреймворков? И, если нет, то как это сделать, учитывая используемые сервисы (Firebase и Heroku).
Заранее благодарствую!
P.S. Ответ ТП Яндекс.Кассы:
Насколько мы понимаем, вы пытаетесь отправить запрос на создание платежа из браузера. Так нельзя и поэтому срабатывает Access to XMLHttpRequest. Для таких запросов доступ не открывается. Для корректного взаимодействия с нашим API, вы должны выполнять запросы не из браузера, а с помощью вашего сервера.
Ответы (1 шт):
В Firebase есть сервис Cloud Functions, я использовал его. Готовый код выглядит так:
exports.yooKassa = functions.https.onRequest((req, res) => {
return cors(req, res, () => {
functions.logger.info("Hello logs!", {structuredData: true});
const shopId = "shopId";
const secretKey = "secretKey";
const t = Buffer.from(`${shopId}:${secretKey}`, "utf8").toString("base64");
axios.post("https://api.yookassa.ru/v3/payments",
{
"amount": {
"value": "1.00",
"currency": "RUB",
},
"confirmation": {
"type": "embedded",
},
"capture": true,
"description": "description",
},
{
headers: {
"Authorization": `Basic ${t}`,
"Content-Type": "application/json",
"Idempotence-Key": Date.now(),
},
})
.then((response) => {
return res.send(response.data);
})
.catch((e) => {
console.log(e);
return res.sendStatus(500);
});
});
});
Cloud Functions в этом случае работают как бэкенд.