开发背景
当后端接口开发完成,并且通过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);
// ...
})();
结语
跨域在工作中经常会遇到,所以跨域请求处理方案务必学会。
我是一名前端程序员,但不止于前端,如果你觉得我写的内容欠妥,欢迎评论区告诉我,大家一起学习,一起进步~