解决 NestJS 项目中接口跨域问题的三种方案

前言

当我们的NestJs后端服务需要被不同源的前端项目访问时,就可能遇到“跨域问题”。跨域问题(CORS,Cross-Origin Resource Sharing)本质上是浏览器的一种安全机制,用于限制一个源(origin)中的web应用如何与另一个源的资源进行交互。幸运的是,NestJs提供了一些简单的方法来解决这一问题。

什么是CORS

CORS是一种机制,它使用额外的HTTP头来告诉浏览器让运行在一个源(domain)上的Web应用被准许访问来自不同源服务器上的指定资源。当一个资源从与该资源本身不同的域、协议或端口请求一个资源时,会发生一个跨源HTTP请求。

NestJS 处理 CORS 问题的三种方法

NestJs允许我们以非常直观的方式启用CORS支持。你可以全局启用它,也可以为特定的路由启用。下面让我们一步一步来看如何操作。

方法一:全局启用CORS

在你的 main.ts文件中,你可以在创建Nest应用时启用CORS:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 启用CORS
  app.enableCors();

  await app.listen(3000);
}
bootstrap();

这将允许所有不同源的客户端请求,没有任何限制。对于某些情况来说,这可能太宽泛了,因为这样设定后,任何网站都可以访问你的服务。

如果你想限制特定的源能够访问服务,可以传入一个选项对象:

app.enableCors({
  origin: '<http://example.com>', // 只有来自 <http://example.com> 的请求才被允许
});

还可以传入更多的配置选项,例如允许的HTTP请求方法、响应中包含的头信息等。

方法二:为特定路由启用CORS

如果你只希望为特定的路由启用CORS,你可以在对应的Controller上使用 @UseCors装饰器。例如:

import { Controller, Get, UseCors } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  @UseCors({
    origin: '<http://example.com>',
  })
  findAll() {
    // ...
  }
}

这将确保只有在访问 /cats路由时,才会启用CORS,并且只有来自 http://example.com的请求可以访问。

方法三:使用中间件来自定义CORS

如果你需要进行更为复杂的CORS配置,或者你希望有完全的控制权,你可以使用 cors这个NPM包,它提供了丰富的配置选项。这个方法也适用于你想对某些路由使用不同的CORS策略的情况。

首先,你需要安装 cors

npm install cors

然后,在你的代码中引入并使用它:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cors from 'cors';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 使用自定义CORS中间件
  app.use(cors({
    origin: '<http://my-mobile-app.com>',
    // 更多的配置选项...
  }));

  await app.listen(3000);
}
bootstrap();

这将允许你把 cors作为一个函数调用并传递配置对象,根据需要进行详细的配置。

高级配置

对于一些更高级的配置,NestJs允许直接传递CORS配置到 NestFactorycreate方法中。例如:

const app = await NestFactory.create(AppModule, {
  cors: {
    origin: '<http://example.com>',
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
    allowedHeaders: 'Content-Type, Accept',
    credentials: true,
  },
});

上面的配置中,我们指定了允许请求的方法、允许的请求头,以及是否允许携带凭证(如cookies)。

注意事项

  1. 安全性:在配置CORS时,不推荐使用通配符()来允许所有来源,因为这可能会使你的应用更容易受到跨站请求伪造(CSRF)或其他攻击。
  2. 环境配置:实际项目中,不同的环境(开发、测试、生产)可能需要不同的CORS设置。推荐将CORS设置存储在环境变量中,并根据当前的运行环境载入。
app.enableCors({
  origin: process.env.CORS_ORIGIN || '*', // 生产环境应指定具体的域名
  methods: process.env.CORS_METHODS || 'GET,HEAD,PUT,PATCH,POST,DELETE',
  allowedHeaders: process.env.CORS_HEADERS || 'Content-Type, Accept',
  credentials: process.env.CORS_CREDENTIALS === 'true', // 请确保实际字符串值是'true'或者'false'
});

  1. 测试: 一旦你配置了CORS,确保你进行了适当的测试,包括从不同的源发起请求,确保配置按预期工作。

具体案例

假设你建立了一个 NestJS 项目,它提供了一些API给移动应用使用,而这个移动应用托管在 http://my-mobile-app.com上。为了允许这个移动应用访问API,我们需要来配置CORS,允许此来源的请求。

在你的 main.ts文件中,你可以如以下方式配置:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    cors: {
      origin: '<http://my-mobile-app.com>', // 只有这个移动应用可以访问
      methods: 'GET,POST', // 只允许GET和POST请求
      credentials: true, // 允许携带凭证信息
    },
  });

  await app.listen(3000);
}
bootstrap();

通过这种方式,我们确保了只有那个特定的移动应用能够访问NestJs服务,并只能通过GET和POST方法。同时,我们也选择接受来自该应用的Cookies或其他认证相关的信息。

总结

NestJS 提供了灵活而又强大的配置选项来处理跨域问题。通过简单的方法可以启用全局CORS或定制特定路由的CORS规则。在处理跨域问题时,不要忘记安全性和合适的环境配置是非常重要的。

配置过后,你的NestJs后端服务就可以平稳地与不同源的前端进行交互了,这样前后端分离的架构就可以无缝协作,最终提供给用户一个完整和流畅的Web体验。

  • 25
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐闻x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值