什么是跨域
跨域(Cross-Origin)指的是在浏览器中,当一个网页的 JavaScript 代码向不同源(协议、域名或端口)的服务器发送请求时,就会发生跨域。例如,如果一个网页在域名为"example.com"的服务器上运行,它的 JavaScript 代码尝试向"api.example2.com"这个不同的域名发送请求,那么就会发生跨域请求。
浏览器实施同源策略(Same-Origin Policy)来限制跨域请求。同源策略要求网页的 JavaScript 只能访问与其来源相同的资源,也就是协议、域名和端口都必须相同。这是为了保障用户的安全性,防止恶意网站获取用户的敏感数据或执行未授权的操作。
跨域可以出现在以下情况下:
域名不同:当请求的域名与当前页面的域名不同。
协议不同:当请求的协议与当前页面的协议不同,例如从 HTTP 页面请求 HTTPS 接口。
端口不同:当请求的端口与当前页面的端口不同。
跨域请求通常是被浏览器阻止的,除非服务器在响应中设置了 CORS(跨域资源共享)头部,或者使用其他跨域解决方案,如 JSONP、代理服务器、WebSocket 等。
在开发 Web 应用程序时,需要注意跨域问题,并根据需要采取适当的措施,以确保跨域请求的安全性和合法性。
同源安全策略
同源安全策略(Same-Origin Policy)是浏览器中一种基本的安全机制,用于保护用户的信息安全和防止恶意网站的攻击。同源安全策略定义了浏览器如何限制跨域请求以及访问跨域资源的规则。
同源安全策略要求在保护用户隐私和安全的前提下,只有当以下三个条件满足时,才允许不受限制地进行跨域资源访问:
协议相同:请求的协议必须与页面的协议一致,即请求的协议必须是HTTP或HTTPS,否则就会被视为跨域请求。
域名相同:请求的域名必须与页面的域名一致,包括子域名。两个页面的域名要完全相同才满足同源策略,例如,和不属于同一个源。http://example.comhttp://www.example.com
端口相同:请求的端口号必须与页面的端口号一致。如果页面使用默认的HTTP端口80或HTTPS端口443,则可以省略端口号,否则必须与页面的端口相同。
同源安全策略的限制适用于许多跨域请求方式,包括通过XMLHttpRequest对象发送的Ajax请求、动态创建的、<script>或<link>标签携带的资源请求等。
如果需要进行跨域请求或访问跨域资源,可以通过以下方式来解决同源安全策略的限制:
跨域资源共享(CORS):服务器在响应中设置CORS头部,允许指定的域名进行跨域访问。
JSONP:利用<script>标签加载外部资源的方式进行跨域请求。
代理服务器:通过自己的服务器作为中间代理,将请求发送到目标服务器并返回结果。在前端我们配置的server proxy代理就是这种
WebSocket:使用WebSocket协议进行全双工通信,不受同源策略限制。
总之,同源安全策略是浏览器的一项重要安全机制,用于限制跨域请求和资源访问,确保用户的隐私和安全。开发者需要在遇到跨域问题时,根据具体情况选择适当的解决方案来绕过同源安全策略的限制。
nestjs解决跨域
Nest 应用程序对象上调用CORS
在nestjs底层中使用了Express的Cors包,用法类似,只需在main.ts中加入一行代码
它可以根据请求(动态)异步定义配置对象,例如
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors({ origin: true, methods: 'GET,PUT,POST', allowedHeaders: 'Content-Type,Authorization', exposedHeaders: 'Content-Range,X-Content-Range', credentials: true, maxAge: 3600, }); await app.listen(3000); } bootstrap();
还可以在app上面配置,它可以接受三种类型的参数,Boolean,Options配置项,回调函数,用法很简单,具体配置项看Cors官方文档 ExpressJS / CORS
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule, { cors: true }); await app.listen(3000); } bootstrap();
中间件(middleware)配置
创建一个中间件类,例如CorsMiddleware
import { Injectable, NestMiddleware } from '@nestjs/common'; @Injectable() export class CorsMiddleware implements NestMiddleware { use(req: any, res: any, next: () => void) { // 在这里配置跨域相关的逻辑 const allowedOrigins = ['http://example1.com', 'http://example2.com']; // 允许的源 const requestOrigin = req.header('Origin'); if (allowedOrigins.includes(requestOrigin)) { res.setHeader('Access-Control-Allow-Origin', requestOrigin); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); } next(); } }
在特定模块中使用
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { CorsMiddleware } from './cors.middleware'; @Module({ imports: [], controllers: [AppController], providers: [AppService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(CorsMiddleware) .forRoutes('*'); // 设置需要应用中间件的路由路径,此处为所有路由 } }
这样,当应用程序接收到请求时,中间件将会被调用进行跨域的处理操作,配置的回调函数将被执行,并且会添加适当的 CORS 头部到响应中。请根据自己的需求进行相应的配置和处理逻辑。
总结
跨域问题是最常见的问题了,现在前端,后端,ng都能解决,而nest底层为我们提供了对应的方法供我们使用,大大简化了开发中遇到的问题。希望能够帮助到大家