Nest和HTTP函数 - CORS

3
我将尝试使用 Firebase HTTP 函数与 Nest 框架进行集成,但是在客户端调用时遇到了 CORS 错误。
以下是我的设置:
declare const require: any
const functions = require('firebase-functions')
const cors = require('cors')({ origin: true })
const express = require('express')

const app = express()
app.use(cors)
const cb = (req, res) => res.status(200).send('success')
app.use(cb)

export default functions.https.onRequest(app)

以上内容完全正常(使用设置为allAuthenticatedUsers的Cloud Functions Invoker角色)。

这是我在Nest中的新设置:

import * as functions from 'firebase-functions'
import { NestFactory } from '@nestjs/core'
import { ExpressAdapter } from '@nestjs/platform-express'
import { Api_Module } from './api.module'
import express from 'express'

const server = express()

const create_nest_server = async (express_instance: express.Express) => {
  const adaptor = new ExpressAdapter(express_instance)
  const app = await NestFactory.create(Api_Module, adaptor)
  app.enableCors({ origin: true })
  await app.init()
  return app
}


create_nest_server(server)
    .then(v => console.log('Nest Ready'))
    .catch(err => console.error('Nest broken', err))


export default functions.https.onRequest(server)

(来自 https://fireship.io/snippets/setup-nestjs-on-cloud-functions/)

这将在客户端会产生以下错误:访问'https://us-central1-<project>.cloudfunctions.net/api-default/'被跨域策略阻止,来源'http://localhost:4200',请求资源没有'Access-Control-Allow-Origin'头。如果一个不透明的响应能够满足您的需求,请将请求的模式设置为“no-cors”以禁用CORS而获取资源。

我也尝试了一些其他的方法,例如:

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

const server = express()
server.use(cors)
// ...the rest

并且:

const create_nest_server = async (express_instance: express.Express) => {
  const adaptor = new ExpressAdapter(express_instance)
  const app = await NestFactory.create(Api_Module, adaptor, {
    cors: {
      origin: true,
    }
  })

  app.enableCors()
  await app.init()
  return app
}

和:

  const nestApp = await NestFactory.create(AppModule, adapter, {
    logger: new CoreLogger(),
    cors: {
      origin: '*',
      methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
      credentials: true,
      preflightContinue: false,
      optionsSuccessStatus: 204,
    },
  })

除了不带任何参数使用app.enableCors()之外。

非常感谢您的帮助。


嗨@skwny,你能否检查一下这里提供的解决方案(https://www.joshmorony.com/an-introduction-to-nestjs-for-ionic-developers/),并验证它是否对你有帮助?它似乎是与你测试过的方法不同的一种方法。 - gso_gabriel
@gso_gabriel 感谢提供链接,但那不是 Firebase 函数集成的示例。我尝试在 Nest 应用程序引导期间使用 app.enableCors(),就像链接中所看到的那样,但遗憾的是没有成功。 - skwny
看看这个答案。我认为它可能会有帮助。 - Ajordat
@Ajordat,我已经看过那篇帖子了,它也不是一个嵌套函数的例子。 - skwny
这是一个使用JS编写的Firebase函数,似乎正是您所需要的。您是否查看了其中显示的建议文档 - Ajordat
@Ajordat,请重新阅读我的最后一条评论和帖子标题。我正在寻找有关在Firebase函数中实现NestJS时如何解决CORS的信息。文档和其他SO答案都没有提供这个。我已经尝试了基于这些材料的不同变体来实现cors支持,但是没有任何效果。如果您有Nest示例或信息,请提供。 - skwny
1个回答

1
假设您的客户端是一个Angular应用程序,如果您正在运行客户端的本地开发版本,则可以使用代理配置文件使您的请求看起来像来自同一来源:

proxy.conf.json

{
    "/api-default": {
        "target": "https://us-central1-<project>.cloudfunctions.net",
        "logLevel": "debug"
    }
}

你需要根据调用你的api的方式来配置这个文件,然后使用以下命令启动本地应用程序:ng serve --proxy-config proxy.conf.json 另一种方法是在NestJS响应中添加适当的CORS响应头:
@Post()
@Header('Access-Control-Allow-Origin', 'http://localhost:4200')
create() {
  return 'This action adds a new cat';
}

这将告诉客户端服务器允许提供的来源。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接