开发背景
当后端接口开发完成,并且通过Swagger测试没问题之后,我便将NestJS服务部署于服务器,前端调用接口时又出现了跨域问题,这时又得继续在后端处理跨域问题。
介绍跨域
在解决跨域问题之前,我们需要先了解什么是跨域?为什么会跨域?
什么是跨域?
跨域指的是web应用中,一个服务请求另一个服务时,一旦协议、ip、端口其中有一个不同,就会被拦截,无法请求。是浏览器提供的一种机制,这种机制叫做同源策略,即当源相同时,是可以互相请求,源不同就会造成跨域。
为什么会跨域?
产生跨域的原因有以下几点:
协议不同:比如https的网站请求http的接口,就会产生跨域。ip不同:比如192.168.31.123的网站请求192.168.31.456的接口,就会产生跨域。当然ip不同也指代域名不同,因为域名最终也是解析到ip的,访问域名其实访问的就是ip。端口不同:比如192.168.31.123:8080的网站请求192.168.31.123:8081的接口,同样会产生跨域。
解决方案
JsonP请求:这是最原始的方案,兼容性好,但仅适用于Get请求。后端处理:后端可以对请求源进行限制,可放开跨域请求。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这个方法,接下来我们来介绍一下这些参数:
origin:源,配置允许的源地址。methods:配置允许跨域的请求方法。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);
// ...
})();
结语
跨域在工作中经常会遇到,所以跨域请求处理方案务必学会。
我是一名前端程序员,但不止于前端,如果你觉得我写的内容欠妥,欢迎评论区告诉我,大家一起学习,一起进步~