[NestJS 带你飞!] DAY28 - CORS

大部分的开发人员在面对前端後端是不同网域的时候,会碰上一个名叫 跨来源资源共享 (Cross-Origin Resource Sharing) 的问题,简称 CORS,那这个 CORS 究竟是什麽东西又为什麽会发生呢?这就让我们来了解一下 CORS 的前因後果吧!

什麽是 CORS?

CORS 是一个控管跨网域请求资源的机制,这个机制可以有效将合法与非合法的跨域存取隔开来,让合法的跨域存取能够顺利取得资源,而这套机制主要是受到 同源政策 的影响。

同源政策

同源政策的概念很简单,假设小华有现在很流行的 Switch,他的朋友小明很想玩,所以他可以直接拿来玩不经过小华同意吗?当然是不行罗,肯定是要经过小华的同意才能够借来玩,同理,假设 A 网域对 B 网域发出了资源请求,这时候 B 网域同意了 A 网域的存取,那麽这个跨网域的存取才会成功,这就产生出了所谓的 CORS 机制。

CORS 运作模式

CORS 的处理方式会在不同的请求状况下而有所不同,请求状况主要分成 简单请求非简单请求

简单请求

简单请求的条件如下:

  • HTTP Method 为 GETPOSTHEAD 其中一个。
  • Header 仅限:AcceptAccept-LanguageContent-LanguageLast-Event-IDDPRSave-DataViewport-WidthWidth
  • Content-Type 的值仅接受:application/x-www-form-urlencodedmultipart/form-datatext/plain

当该请求为简单请求时,浏览器会判断其是否为跨域存取并会在 Header 添加相关资讯,若该请求并不属於合法范围的话,这个跨域存取将会无效。

非简单请求

当该请求为非简单请求时,会先向跨域的服务器端发送 OPTION 的请求,该服务器会返回许可规则的 Header,在收到规则後,浏览器会判断这个非简单请求是否符合许可规则,如果符合就会向跨域的服务器端发送该请求来存取资源。

Nest 与 CORS

Nest 与 Express 一样,预设是不允许跨域存取的,若要启用的话,只需要在 main.ts 中做配置即可,调用 appenableCors(options?: CorsOptions | CorsOptionsDelegate<any>) 这个方法,就可以顺利启用 CORS:

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  await app.listen(3000);
}
bootstrap();

Nest 的 CORS 功能其实也是将 Express 的 cors 套件进行打包,并直接内建在 Nest 中,所以 options 的配置与 cors 这个套件的配置项目是相同的。

还有另一种开启 CORS 的方法,就是直接在 NestFactorycreate 方法中带入 cors 选项,以下方程序码为例,直接带入 true 的效果与 enableCors() 是相同的:

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();

小结

CORS 的问题可以说是非常容易遇到,特别是在前後端分离的情况下。真正上线的时候,通常 不会 允许所有跨域存取都是许可的,都会针对特定网域设置白名单等,所以产品上线的时候千万要记得配置 options 啊!

参考资料

MDN CORS


<<:  Day 29 - 将 Yacht 後台储存资料提取後,送至前台渲染 Layout&deck 及 Video 版面内容区块 - 嵌入 YouTube 影片 - ASP.NET Web Forms C#

>>:  [Day 30] 应用三:脸部追踪

[笔记][JavaScript] - 随机取出阵列元素之值

目的:能产生简易版本乱数抽签系统 先从 Math.random() 语法了解 再带入至 Math.f...

关於继承

什麽是继承 In object-oriented programming, inheritance ...

Day 0x11 - 建立信用卡付款的订单

0x1 前言 之前都是建立付款方式为 ATM 的订单,另一个信用卡的流程都没跑过,今天就是要来跑一下...

Day 08-Code 要 Review,Infrastrcture 岂不 Review?吾未见其明也

Code 要 Review,Infrastrcture 岂不 Review?吾未见其明也 CI/CD...

[Day7] 实作 - 敌人篇

如果你是熟悉RPG Maker的人 一定知道各式各样实作敌人的方式 其中当然包括使用引擎内建的UI来...