为啥只有在部署到 Firebase 时才会在 Node.js 和 Angular 之间出现 CORS 错误?
Posted
技术标签:
【中文标题】为啥只有在部署到 Firebase 时才会在 Node.js 和 Angular 之间出现 CORS 错误?【英文标题】:Why do I get a CORS error between Node.js and Angular only when deployed to Firebase?为什么只有在部署到 Firebase 时才会在 Node.js 和 Angular 之间出现 CORS 错误? 【发布时间】:2021-09-27 12:50:25 【问题描述】:错误:Access to XMLHttpRequest at 'https://us-central1-yalebot-n9xq.cloudfunctions.net/dialogflowGateway' from origin 'https://yalebot-n9xq.web.app' 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.
在本地主机上运行或通过 ngrok
暴露在本地运行的 webhook 时,我没有出错。
将credentials
和methods
字段添加到cors
没有任何作用。
节点(index.js):
const functions = require("firebase-functions");
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require("firebase-admin");
const serviceAccount = require("./service-account.json");
const cors = require('cors')(origin:true,
credentials:true,
methods: 'POST,GET,PUT,OPTIONS,DELETE');
const SessionsClient = require('dialogflow');
// admin.initializeApp(
// credential: admin.credential.cert(serviceAccount),
// databaseURL: "https://yalebot-n9xq-default-rtdb.firebaseio.com"
// );
// var db = admin.firestore();
//Endpoint that Joins FrontEnd and Dialogflow API
exports.dialogflowGateway = functions.https.onRequest((request, response) =>
cors(request, response, async () =>
const queryInput, sessionId = request.body;
console.log("Gateway");
const sessionClient = new SessionsClient( credentials: serviceAccount );
const session = sessionClient.sessionPath('yalebot-n9xq', sessionId);
const responses = await sessionClient.detectIntent( session, queryInput);
const result = responses[0].queryResult;
response.header('Access-Control-Allow-Origin', "*");
response.header('Access-Control-Allow-Headers', true);
response.header('Access-Control-Allow-Credentials', 'Content-Type');
response.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
response.send(result);
);
);
const WebhookClient = require('dialogflow-fulfillment');
//Path from DialogflowAPI to Further Processsing
exports.dialogflowWebhook = functions.https.onRequest(async (request, response) =>
response.header('Access-Control-Allow-Origin', "*");
response.header('Access-Control-Allow-Headers', true);
response.header('Access-Control-Allow-Credentials', 'Content-Type');
response.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
console.log('Webhook');
const agent = new WebhookClient( request, response );
const result = request.body.queryResult;
async function fallbackHandler(agent)
agent.add("I do not understand the words that are coming out of your mouth.");
let intentMap = new Map();
intentMap.set('Default Fallback Intent', fallbackHandler);
agent.handleRequest(intentMap);
);
Component.ts(发布请求的地方)
import Component, OnInit, ChangeDetectionStrategy from '@angular/core';
import HttpClient from '@angular/common/http';
const dialogflowUrl = "https://us-central1-yalebot-n9xq.cloudfunctions.net/dialogflowGateway"
@Component(
selector: 'app-chatbot',
templateUrl: './chatbot.component.html',
styleUrls: ['./chatbot.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
)
export class ChatbotComponent implements OnInit
messages = Array();
loading = false;
// Random ID to maintain session with server
sessionId = Math.random().toString(36).slice(-5);
constructor(private http: HttpClient)
ngOnInit()
this.addBotMessage("Hi. I'm MyChatBot. Let's talk about HIV testing. Respond by typing to say which topic you want to learn more about. PrEP, Get Self-Testing Kits, Learn about Self-Testing, HIV Testing (in general)");
handleUserMessage(event:any)
const text = event.message;
this.addUserMessage(text);
this.loading = true;
// Make the request
this.http.post<any>(
dialogflowUrl,
sessionId: this.sessionId,
queryInput:
text:
text,
languageCode: 'en-US'
)
.subscribe(res =>
const fulfillmentText = res;
this.addBotMessage(fulfillmentText);
this.loading = false;
);
addUserMessage(text:string)
this.messages.push(
text,
sender: 'You',
reply: true,
date: new Date()
);
addBotMessage(text:string)
this.messages.push(
text,
sender: 'ZhaoBot',
date: new Date()
);
【问题讨论】:
【参考方案1】:事实证明,还必须在 Dialogflow 中设置 Access-Control-Allow-Origin
标头。
有一个选项可以在您指定 webhook 的 url 的下方设置字段。
部署到 Firebase 的 Node JS 和 DialogFlow 都算作“服务器”对我来说并不明显。
【讨论】:
以上是关于为啥只有在部署到 Firebase 时才会在 Node.js 和 Angular 之间出现 CORS 错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥只有在 Windows 控制台程序中按 Ctrl+Z 时才会终止输入? [复制]
为啥我的网站的谷歌地图部分只有在用户删除他/她的 cookie 时才会更新?
为啥只播放 UNNotificationSound 的前 5 秒