【问题标题】: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 时,我没有出错。

credentialsmethods 字段添加到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()
    });
  }

}

【问题讨论】:

    标签: node.js angular firebase cors


    【解决方案1】:

    事实证明,还必须在 Dialogflow 中设置 Access-Control-Allow-Origin 标头。

    有一个选项可以在您指定 webhook 的 url 的下方设置字段。

    部署到 Firebase 的 Node JS 和 DialogFlow 都算作“服务器”对我来说并不明显。

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 1970-01-01
      • 2021-05-21
      • 2013-04-23
      • 1970-01-01
      • 2023-04-02
      • 2022-06-20
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多