CORS 的原理是什么~

82 阅读3分钟

跨源资源共享(CORS)是浏览器实现的一项重要安全机制,用于保护用户免受潜在恶意脚本的侵害。然而,它也是开发者(尤其是刚接触网页开发的新手)常见的困扰来源。本文旨在揭开CORS的神秘面纱,解释其存在的原因,并提供解决CORS相关问题的策略。

什么是CORS?

CORS是浏览器实现的一项安全功能,用于控制网页从一个外部域访问另一个域的资源(如API或字体)。

同源策略

要理解CORS,首先需要了解同源策略。这是浏览器的一项基本安全措施,限制从一个源加载的文档或脚本如何与另一个源的资源进行交互。源由协议、域名和端口的组合定义。

例如:

CORS存在的原因

CORS的引入是为了让服务器能够指定哪些源可以访问其资源,从而以可控的方式放宽同源策略。这对于现代网页应用至关重要,因为它们经常需要向托管在不同域上的API发起请求。

常见的CORS错误

开发者经常在尝试从网页应用向不同域的API发起请求时遇到CORS错误。典型的CORS错误可能如下所示:

从源 'https://myapp.com' 访问 'https://api.example.com/data' 的请求已被CORS策略阻止:  
请求的资源上未找到 'Access-Control-Allow-Origin' 标头。  

CORS的工作原理

当网页应用发起跨源请求时:

  1. 浏览器发送请求时附带一个Origin标头,指明请求页面的源。
  2. 服务器可以响应以下内容:
    • 一个Access-Control-Allow-Origin标头,指定允许的源。
    • 其他CORS标头,控制允许的方法、标头等。
  3. 如果服务器的响应未包含适当的CORS标头,浏览器会阻止该响应。

解决CORS问题

1. 服务器端配置

解决CORS问题最合适的方法是配置服务器发送正确的CORS标头。通常包括:

  • 设置Access-Control-Allow-Origin标头以指定允许的源。
  • 根据需要配置其他CORS标头(如Access-Control-Allow-Methods、Access-Control-Allow-Headers)。

Node.js与Express的示例:

const express = require('express');  
const cors = require('cors');  
const app = express();  

app.use(cors({  
  origin: 'https://myapp.com'  
}));  

// 你的路由代码  

2. 使用代理

如果无法控制服务器,可以设置一个代理服务器来添加必要的CORS标头。这在开发环境中经常使用。

使用Create React App代理功能的示例:
在package.json中:

{  
  "proxy": "https://api.example.com"  
}  

3. JSONP(仅适用于GET请求)

JSONP(带填充的JSON)是一种较旧的技术,通过使用不受同源策略限制的script标签,可以绕过CORS限制发起GET请求。

function handleResponse(data) {  
  console.log(data);  
}  

const script = document.createElement('script');  
script.src = 'https://api.example.com/data?callback=handleResponse';  
document.body.appendChild(script);  

注意:JSONP被认为已经过时,且安全性不如正确的CORS实现。

最佳实践

  1. 理解安全影响:不要盲目绕过CORS。它的存在是有原因的。
  2. 使用特定源:在生产环境中避免使用Access-Control-Allow-Origin: *。明确指定允许的源。
  3. 使用环境特定的配置:为开发和生产环境设置不同的CORS配置。
  4. 处理预检请求:对于非简单请求,正确处理OPTIONS请求。
  5. 牢记安全性:CORS是由浏览器强制执行的,服务器端的安全措施仍然必要。

结论

尽管CORS可能令人沮丧,但它是一项重要的安全功能。通过理解其工作原理并实施正确的解决方案,开发者可以创建安全且功能完善的网页应用,实现与不同域资源的交互。

记住,如果遇到CORS问题,第一步是确定是否对服务器有控制权。如果有,实现正确的CORS标头是最佳解决方案。如果没有,可以考虑使用代理,或者对于简单的GET请求,最后考虑使用JSONP。