什么是CORS?

在Web开发中,CORSCross-Origin Resource Sharing 的缩写,意为“跨源资源共享”。

CORS 是一种网络浏览器的安全机制,它允许运行在一个源(origin,即协议、域名和端口的组合)上的 Web 应用程序访问另一个源的资源。它是一种基于HTTP头的机制,这个机制允许服务器标示除了它自己以外的其他源(域名+协议+端口),使得浏览器允许这些被标示的源访问加载自己的资源。

总的来说,CORS是解决浏览器同源策略限制,实现安全跨源通信的一种标准机制。它通过浏览器和服务器之间的HTTP头协商,明确哪些跨源请求是被允许的,从而让Web应用能够更灵活地获取和使用来自不同源的资源。

为什么需要CORS?

这要从浏览器的“同源策略(Same-Origin Policy)”说起。同源策略是浏览器的一个重要安全机制,它限制了从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这里的“源”通常由 协议(protocol)、域名(domain)和端口(port) 三部分组成。如果这三者中有任何一个不同,就被认为是不同的源。

同源策略的存在是为了防止恶意网站读取其他网站上的敏感数据(例如在网上银行的登录信息)。默认情况下,浏览器会阻止网页中的脚本发起跨源的HTTP请求。

然而,在现代Web应用中,跨源访问资源是非常常见的需求,例如:

  • 前端代码需要调用不同域上的后端API。

  • 网页从一个域名加载,但需要从另一个域名请求 API 数据。

  • 网页需要加载其他域上的字体、图片或脚本。

  • 使用第三方服务(如地图服务、支付接口等)。

  • 网页需要加载存储在 CDN 或对象存储服务(如 OSS)上的图片、字体、脚本或其他资源,而这些服务的域名与网页的域名不同。

为了在保证安全性的同时满足这些跨源访问的需求,W3C(万维网联盟)推出了CORS标准。

CORS如何工作?

CORS 的工作原理是:

  1. 浏览器在发起跨源请求时,会额外发送一个 Origin 头部,表明请求的来源。
  2. 服务器收到请求后,会检查这个 Origin 头部。
  3. 如果服务器允许该来源的请求,它会在响应头中加入 Access-Control-Allow-Origin 头部,包含允许的来源(或者 * 表示允许所有来源)。
  4. 浏览器收到响应后,检查 Access-Control-Allow-Origin 头部。如果该头部允许当前请求的来源,浏览器就允许网页访问响应数据;否则,浏览器就会阻止这个响应。

预检请求(Preflight Request)

对于一些“非简单”的请求(例如使用了非 GET/HEAD/POST 方法,或者包含了自定义头部等),浏览器还会先发送一个 **预检请求 (Preflight request)**,使用 OPTIONS 方法,询问服务器是否允许实际的跨源请求。服务器返回 OPTIONS 响应,其中包含允许的方法、头部等信息。浏览器根据预检响应决定是否发送实际请求。

对于一些“复杂”的跨源请求,例如使用了PUTDELETE等HTTP方法,或者发送了特定的HTTP头,浏览器会先自动发起一个类型为OPTIONS的“预检请求”。这个预检请求的目的是向服务器询问是否允许后续的实际请求。服务器在收到预检请求后,会根据CORS配置返回响应,告知浏览器允许的HTTP方法、头等信息。只有预检请求成功后,浏览器才会发送实际的跨源请求。

因此,如果需要在网页中通过 JavaScript 等方式访问存储在 OSS 中的资源,而网站域名和 OSS 的域名不同,就需要配置 OSS 的 CORS 规则,允许网站所在的源访问 OSS 的资源,这样浏览器才不会阻止这些请求。


以下 类型的资源 所在的服务器或服务提供商 通常会配置相对宽松的 CORS 策略 (例如设置 Access-Control-Allow-Origin: * 或允许常见的 Origin):

  1. 公共的静态资源: 托管在 CDN 上或云存储(如 OSS)中用于网站的公共图片、CSS、JavaScript 库、字体文件等。这些资源通常设计成可以被任何网站引用,所以服务器会配置宽松的 CORS 策略以便浏览器可以跨域加载和使用它们
  2. 公共开放 API 的响应: 一些提供公开数据的 API 服务,为了方便第三方开发者调用,其服务器会配置 CORS 允许来自不同源的请求。

以下是一些可能触发 CORS 检查的常见文件或资源加载场景(当它们是跨源时):

  1. 通过 XMLHttpRequestWorkspace API 获取的数据: 这是最典型的触发 CORS 的场景,用于获取 JSON、XML、文本等数据。如果服务器没有返回正确的 CORS 头部,浏览器会阻止脚本读取响应内容。
  2. 用于 <canvas> 绘制的图片: 如果你使用 <img> 标签加载跨域图片,然后尝试将这张图片绘制到 <canvas> 上,并且后续需要读取 canvas 的内容(如使用 toDataURL()getImageData()),则会触发 CORS 检查。这是为了防止脚本绕过同源策略获取跨域图片的数据。可以给 <img> 标签设置 crossorigin 属性来启用 CORS 请求,但需要服务器允许。
  3. Web 字体: 通过 CSS 的 @font-face 规则加载跨域字体文件(如 .woff, .ttf)。如果服务器没有正确配置 CORS,浏览器可能会阻止字体加载。
  4. 用于 WebGL 纹理的图片: 在 WebGL 中加载跨域图片作为纹理使用时,会触发 CORS 检查。
  5. 用于 <video><audio> 并需要处理的媒体文件: 如果通过 HTML5 的 <video><audio> 标签加载跨域媒体文件,并且需要使用 Web Audio API 等对其进行处理时,会触发 CORS 检查。

遇到的问题(网站无法加载OSS的字体资源)

当网站请求OSS上的字体资源时,返回CORS错误信息如下图所示,虽然状态代码是200,表示服务器返回了资源,但是资源被浏览器拒绝加载,所以在css预设的字体无法加载到网页上,最终展现的并不是我想要的字体。要解决这个问题,就要在阿里云的CDN和OSS配置上进行跨源相关的配置

GET请求信息

字体CORS错误

一开始我设置了OSS相关的跨院设置,但还是报上面的错误,我还以为是设置不对;其实是因为我使用了CDN,网站进行请求时请求的是CDN资源,而不是OSS的源站资源,因为我没对CDN做配置,所以还是有CORS错误,我需要同时在OSS和CDN上做跨域的相关配置,这样无论是请求源站资源还是CDN资源,都能保证正确加载字体

OSS的相关配置

OSS的相关配置如下,进入bucket–>跨域设置–>创建规则–>编辑下列规则

OSS配置

CDN相关配置

进入CDN控制台–>域名管理(statics.liuhengfeng.xyz)–>管理–>缓存配置–>节点HTTP响应头,填入下列配置

CDN配置

然后到刷新预热界面,强制刷新CDN缓存,也就是更改了字体配置的custom.min.css文件,然后重新访问网站,就能发现网站已经能正确加载字体了,解决了CORS跨域错误的问题

刷新custom.min.css

刷新CDN资源

正确响应字体文件

CDN的刷新预热功能

CDN(Content Delivery Network)的刷新预热是两个常用的缓存管理功能,它们的目的是为了更有效地管理和更新 CDN 边缘节点上的缓存内容,最终提升用户访问体验和减轻源站(原始服务器)的压力。

简单来说:

  • 刷新 (Refresh) 是为了让 CDN 强制更新已经缓存在边缘节点上的内容。
  • 预热 (Preload / Prewarm) 是为了提前把内容加载到 CDN 的边缘节点上,以便用户第一次访问时就能直接从 CDN 获取,而不是回源(回源指边缘节点需要向源站请求内容)。

CDN 刷新 (Refresh)

  • 作用: 当你更新了源站上的某个文件(例如,修改了一张图片,更新了 CSS 文件,改了网页内容),但 CDN 边缘节点仍然缓存着旧版本的文件。如果不进行刷新,用户在 CDN 缓存过期(TTL, Time To Live)之前访问到的仍然是旧版本。刷新操作就是用来强制 CDN 边缘节点上的缓存失效,让它们知道需要去源站获取最新版本。

CDN 预热 (Preload / Prewarm)

  • 作用: 当发布了新的内容(例如,一篇新的文章、一个新产品页面、一个新的软件版本),或者 CDN 缓存过期后,用户第一次访问这些内容时,边缘节点是没有缓存的(或者缓存已过期)。这时边缘节点就需要回源站拉取内容,这会导致第一次访问的速度较慢(也增加了源站的压力)。预热就是为了在预期用户访问这些新内容之前,主动地将这些内容从源站拉取到 CDN 的边缘节点上。

  • 刷新: 确保用户访问到的内容是最新的,解决内容更新不同步的问题。

  • 预热: 提高用户首次访问新内容或热点内容的速度,降低第一次访问的回源延迟,减轻源站瞬时压力。


  • 刷新 = 让旧缓存失效,下次访问时拉新的。
  • 预热 = 提前把内容拉到 CDN 上,让第一次访问就快。

关于CDN的费用问题

CDN的好处是便宜的流量费+边缘服务器快速响应,但是我的个人网站平时访问量接近于无,产生的流量费和请求量也是很低很低,而CDN一年500GB的加速包就要66¥,这个价格已经顶得上我一年的OSS下行流量费+请求费用了,而且一年还用不完500GB,所以其实没有必要开通CDN,不用的话还能剩下一大笔钱。

在对象存储服务(如阿里云 OSS)中,主要的请求类型通常是用于对象操作的 RESTful API 方法,其中:

  • PUT 通常用于上传完整的对象或通过分块上传方式上传对象。
  • GET 用于下载对象。
  • DELETE 用于删除对象。
  • HEAD 用于获取对象的元数据而无需下载对象内容。

“请求费用”部分确实只明确列出了 PUT 类型请求GET 类型请求 的收费标准,没有单独列出 POST 请求。而且我也确实没用到POST请求;传输加速功能也未使用;

OSS详细的计费规则如下(按量付费-资费详情):

资费项/计费项 标准型单价 低频访问型单价 归档型单价 冷归档型单价 深度冷归档型单价
存储费用 数据存储(本地冗余存储) 0.12 元/GB/月 0.08 元/GB/月 0.033 元/GB/月 0.015 元/GB/月
数据存储(同城冗余存储) 0.15 元/GB/月 0.10 元/GB/月 0.033 元/GB/月
无地域属性存储容量 0.12 元/GB/月
临时存储容量费用 临时存储容量(本地冗余) 0.12 元/GB/月
流量费用 内/外网流入流量(数据上传到 OSS) 免费 免费 免费 免费
内网流出流量(通过同地域 ECS 使用内网 Endpoint,下载 OSS 的数据) 免费 免费 免费 免费
外网流出流量 00:00 - 08:00(闲时):0.25 元/GB
08:00 - 24:00(忙时):0.50 元/GB
00:00 - 08:00(闲时):0.25 元/GB
08:00 - 24:00(忙时):0.50 元/GB
00:00 - 08:00(闲时):0.25 元/GB
08:00 - 24:00(忙时):0.50 元/GB
00:00 - 08:00(闲时):0.25 元/GB
08:00 - 24:00(忙时):0.50 元/GB
CDN 回源流出流量 0.15 元/GB 0.15 元/GB 0.15 元/GB 0.15 元/GB
跨区域复制流量费用 复制到中国内地区域 0.50 元/GB 0.50 元/GB 0.50 元/GB
复制到无地域属性(中国内地) 0.50 元/GB
复制到中国香港 0.75 元/GB 0.75 元/GB 0.75 元/GB
复制到新加坡 0.51 元/GB 0.51 元/GB 0.51 元/GB
复制到美国西部 1(硅谷) 0.50 元/GB 0.50 元/GB 0.50 元/GB
复制到美国东部 1(弗吉尼亚) 0.50 元/GB 0.50 元/GB 0.50 元/GB
复制到亚太东北 1(日本) 0.812 元/GB 0.812 元/GB 0.812 元/GB
复制到欧洲中部 1(德国) 0.50 元/GB 0.50 元/GB 0.50 元/GB
复制到欧洲西部 1(英国) 0.50 元/GB 0.50 元/GB 0.50 元/GB
复制到中东东部 1(迪拜) 2.00 元/GB 2.00 元/GB 2.00 元/GB
复制到亚太东南 2(澳大利亚) 0.90 元/GB 0.90 元/GB 0.90 元/GB
复制到亚太东南 3(马来西亚) 0.522 元/GB 0.522 元/GB 0.522 元/GB
复制到亚太南部 1(印度) 0.50 元/GB 0.50 元/GB 0.50 元/GB
复制到亚太东南 5(印度尼西亚) 0.51 元/GB 0.51 元/GB 0.51 元/GB
跨区域复制 RTC 费用 跨区域复制 RTC 0.1 元/GB 0.1 元/GB 0.1 元/GB
请求费用 PUT 类型请求 每月每地域 0 - 500 万次:免费
>500 万次:0.01 元/万次
0.1 元/万次 0.1 元/万次 0.1 元/万次
GET 类型请求 每月每地域 0 - 2000 万次:免费
>2000 万次:0.01 元/万次
0.1 元/万次 0.1 元/万次 0.1 元/万次
取回请求 高优先级:30 元/万次
标准:3 元/万次
批量:0.3 元/万次
数据处理费用 图片处理 每月 0 - 10 TB:免费
>10 TB:0.025 元/GB
每月 0 - 10 TB:免费
>10 TB:0.025 元/GB
每月 0 - 10 TB:免费
>10 TB:0.025 元/GB
每月 0 - 10 TB:免费
>10 TB:0.025 元/GB
图片高级压缩 低规格(800×600 以下):0.025 元/千次
中规格(800×600 以上):0.1 元/千次
低规格(800×600 以下):0.025 元/千次
中规格(800×600 以上):0.1 元/千次
低规格(800×600 以下):0.025 元/千次
中规格(800×600 以上):0.1 元/千次
低规格(800×600 以下):0.025 元/千次
中规格(800×600 以上):0.1 元/千次
视频截帧 0.1 元/千张 0.1 元/千张 0.1 元/千张 0.1 元/千张
Select 扫描 0.0122 元/GB 0.0122 元/GB 0.05 元/GB 0.05 元/GB
数据取回 免费 0.0325 元/GB 0.06 元/GB 高优先级:0.2 元/GB
标准:0.06 元/GB
批量:0.03 元/GB
归档直读数据取回容量 0.2 元/GB
对象标签费用 对象标签 0.0567 元/万个/月 0.0567 元/万个/月 0.0567 元/万个/月 0.0567 元/万个/月
传输加速费用 从中国内地以外地区,访问中国内地的 OSS 上传加速(AccO2MIn) 1.25 元/GB 1.25 元/GB 1.25 元/GB 1.25 元/GB
从中国内地以外地区,访问中国内地的 OSS 下载加速(AccO2MOut) 1.25 元/GB 1.25 元/GB 1.25 元/GB 1.25 元/GB
从中国内地地区,访问中国内地的 OSS 上传加速(AccM2MIn) 0.50 元/GB 0.50 元/GB 0.50 元/GB 0.50 元/GB
从中国内地地区,访问中国内地的 OSS 下载加速(AccM2MOut) 0.50 元/GB 0.50 元/GB 0.50 元/GB 0.50 元/GB
DDoS防护费用 高防资源预留费 10 元/小时
高防资源提前释放费(少于 7 天) 10 元/小时
高防流量防护费 0.05 元/GB
高防请求防护费 0.01 元/万次
敏感数据保护费用 敏感数据保护 0.20 元/GB 0.20 元/GB 0.20 元/GB 0.20 元/GB
内容安全 内容安全 5 元/万次 5 元/万次 5 元/万次 5 元/万次
恶意文件检测 恶意文件检测 10 元/万次 10 元/万次 10 元/万次 10 元/万次
元数据管理 OSS - HDFS 元数据管理 0.30 元/万个 0.30 元/万个 0.30 元/万个 0.30 元/万个
其他费用 OSS 加速器 0.70 元/GB/月 0.70 元/GB/月 0.70 元/GB/月 0.70 元/GB/月