返回

一文读懂跨域资源共享(CORS)的原理与实现

闲谈




浏览器同源策略和跨域请求

浏览器同源策略(Same Origin Policy,SOP)是一项重要的安全机制,旨在防止恶意网站或脚本访问用户存储在浏览器中的敏感信息,如 cookie 和会话数据。SOP 规定,只有来自相同来源(协议、端口和主机)的请求才能访问这些信息。

跨域请求是指从一个源发出的请求,其目标源与请求源不同。由于 SOP 的限制,跨域请求通常会被浏览器阻止。

CORS:跨域资源共享

跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种机制,它允许浏览器在一定条件下绕过 SOP 的限制,向跨域资源发出请求。CORS 通过使用 HTTP 头部和预检请求来实现跨域请求。

HTTP 头部

CORS 使用以下 HTTP 头部来实现跨域请求:

  • Access-Control-Allow-Origin: 该头部指定哪些来源可以访问服务器资源。
  • Access-Control-Allow-Methods: 该头部指定允许哪些 HTTP 方法用于跨域请求。
  • Access-Control-Allow-Headers: 该头部指定允许哪些 HTTP 头部在跨域请求中使用。
  • Access-Control-Allow-Credentials: 该头部指定是否允许跨域请求携带凭证(如 cookie 和 HTTP 身份验证凭据)。

预检请求

对于某些类型的跨域请求,浏览器会首先发送一个预检请求(OPTIONS 请求)到服务器,以检查服务器是否允许该请求。预检请求包含以下 HTTP 头部:

  • Origin: 该头部指定请求的来源。
  • Access-Control-Request-Method: 该头部指定跨域请求的方法。
  • Access-Control-Request-Headers: 该头部指定跨域请求中使用的 HTTP 头部。

服务器收到预检请求后,会返回一个预检响应,其中包含以下 HTTP 头部:

  • Access-Control-Allow-Origin: 该头部指定哪些来源可以访问服务器资源。
  • Access-Control-Allow-Methods: 该头部指定允许哪些 HTTP 方法用于跨域请求。
  • Access-Control-Allow-Headers: 该头部指定允许哪些 HTTP 头部在跨域请求中使用。
  • Access-Control-Allow-Credentials: 该头部指定是否允许跨域请求携带凭证(如 cookie 和 HTTP 身份验证凭据)。

浏览器收到预检响应后,如果发现服务器允许该跨域请求,则会发送实际的跨域请求。否则,浏览器会阻止该跨域请求。

如何使用 CORS

要使用 CORS,您需要在服务器端和客户端分别进行配置。

服务器端配置

在服务器端,您需要配置以下内容:

  1. 确保您的服务器支持 CORS。
  2. 在服务器端代码中,添加相应的 HTTP 头部来允许跨域请求。例如,在 Node.js 中,您可以使用以下代码来允许来自所有来源的跨域请求:
app.use(cors());

客户端配置

在客户端,您需要配置以下内容:

  1. 在发送跨域请求之前,您需要在请求中添加相应的 HTTP 头部。例如,在 JavaScript 中,您可以使用以下代码来发送跨域请求:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/api/data');
xhr.setRequestHeader('Origin', 'https://example.org');
xhr.send();
  1. 您还可以使用 Fetch API 来发送跨域请求。Fetch API 是一个现代的浏览器 API,它允许您使用 Promise 来发送网络请求。Fetch API 会自动处理 CORS。

CORS 的常见问题和解决方案

在使用 CORS 时,您可能会遇到以下常见问题:

  1. 跨域请求被阻止: 确保您已在服务器端和客户端正确配置了 CORS。
  2. 跨域请求携带凭证时被阻止: 确保您已在服务器端和客户端正确配置了 CORS,并确保您的服务器支持凭证。
  3. 预检请求失败: 确保您已在服务器端和客户端正确配置了 CORS,并确保您的服务器支持预检请求。

结论

CORS 是一个强大的机制,它允许浏览器在一定条件下绕过 SOP 的限制,向跨域资源发出请求。CORS 通过使用 HTTP 头部和预检请求来实现跨域请求。要使用 CORS,您需要在服务器端和客户端分别进行配置。在使用 CORS 时,您可能会遇到一些常见问题,但这些问题通常都可以通过正确配置 CORS 来解决。