NestJS解决跨域

2,128 阅读3分钟

开发背景

当后端接口开发完成,并且通过Swagger测试没问题之后,我便将NestJS服务部署于服务器,前端调用接口时又出现了跨域问题,这时又得继续在后端处理跨域问题。

介绍跨域

在解决跨域问题之前,我们需要先了解什么是跨域为什么会跨域

什么是跨域?

跨域指的是web应用中,一个服务请求另一个服务时,一旦协议ip端口其中有一个不同,就会被拦截,无法请求。是浏览器提供的一种机制,这种机制叫做同源策略,即当源相同时,是可以互相请求,源不同就会造成跨域。

为什么会跨域?

产生跨域的原因有以下几点:

  1. 协议不同:比如https的网站请求http的接口,就会产生跨域。
  2. ip不同:比如192.168.31.123的网站请求192.168.31.456的接口,就会产生跨域。当然ip不同也指代域名不同,因为域名最终也是解析到ip的,访问域名其实访问的就是ip
  3. 端口不同:比如192.168.31.123:8080的网站请求192.168.31.123:8081的接口,同样会产生跨域。

解决方案

  1. JsonP请求:这是最原始的方案,兼容性好,但仅适用于Get请求。
  2. 后端处理:后端可以对请求源进行限制,可放开跨域请求。
  3. Nginx代理:当前端访问一个跨域请求时,可使用Nginx将本机的ip端口代理到与请求一致的ip端口

Nest解决

NestJS帮我们内置有处理跨域的方案:点此查看

新建Cors类

我这里仍然使用面向对象的方式去创建一个Cors类

src/lib目录下新建一个Cors.ts文件。

首先完成一个的基础骨架:

export class Cors {
  constructor() {}
}

这个有一个私有属性app,这个app是必传参数,并在constructor中赋值:

export class Cors {
  private app = null;
  constructor(app) {
    this.app = app;
  }
}

接下来有一个方法(handle)用来处理跨域,并在constructor中调用:

export class Cors {
  private app = null;
  constructor(app) {
    this.app = app;
    this.handle();
  }
  handle() {
    this.app.enableCors({
      origin: "*",
      allowedHeaders: ['Authorization', 'content-type'],
      methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
    });
   }
}

其实最关键的也就是this.app.enableCors这个方法,接下来我们来介绍一下这些参数:

  1. origin:源,配置允许的源地址。
  2. methods:配置允许跨域的请求方法。
  3. allowedHeaders配置允许的请求头。

这里是GitHub文档介绍

image.png

英文不好的可以看下图翻译

Snipaste_2023-04-15_15-50-33.png

如何使用

最后我们来看一下如何使用,在src/main.ts中的bootstrap程序启动后调用Cors类即可成功。

// ...
import { Cors } from "./lib/Cors";

// 启动程序
(async function bootstrap() {
  // 加载主模块到Nest工厂
  const app = await NestFactory.create(AppModule);

  // 解决跨域
  new Cors(app);

  // ...
})();

结语

跨域在工作中经常会遇到,所以跨域请求处理方案务必学会。

我是一名前端程序员,但不止于前端,如果你觉得我写的内容欠妥,欢迎评论区告诉我,大家一起学习,一起进步~