Featured image of post CORS 的工作原理以及修复访问阻止错误Featured image of post CORS 的工作原理以及修复访问阻止错误

CORS 的工作原理以及修复访问阻止错误

了解预检检查、来源检查和协议设置(例如 Access-Control-Allow-Origin)以修复 CORS。

介绍

CORS(资源共享)是一种浏览器安全,用于控制来自一个源的网页如何请求来自不同源的资源。当https://app.example.com处的前端尝试从https://api.example.org获取数据时,浏览器默认强制执行同源策略。CORS提供了一种通过HTTP标头来放宽此策略的受控方法。本文介绍了完整的CORS流程、预检请求以及如何修复常见的阻止访问错误。


同源政策

起源方案主机端口的组合定义:

网址产地
占位符_0占位符_1
占位符_0同源
占位符_0不同产地(不同方案)
占位符_0不同来源(不同主机)
占位符_0不同产地(不同口岸)

默认情况下,同源策略会阻止读取跨源响应。这可以防止恶意站点窃取其他来源的数据。


简单请求与预检请求

CORS区分简单请求和触发预检的请求。

如果满足所有这些条件,请求就是简单

  • 方法:GETHEADPOST
  • 内容类型:application/x-www-form-urlencodedmultipart/form-datatext/plain
  • 没有自定义标头

对于简单请求,浏览器直接发送请求并检查响应中的CORS标头。

所有其他请求都会触发触发预检 — 实际上在发送的OPTIONS请求之前:

OPTIONS /api/data HTTP/1.1
Host: api.example.org
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

服务器必须使用适当的 CORS 标头进行响应,浏览器才能继续。


核心 CORS 响应标头

服务器通过这些响应标头控制CORS行为:

标题目的
占位允许符_0指定哪些来源
占位允许符_0上线的 HTTP 方法
占位允许符_0上市的自定义请求标头
占位允许符_0是否权限(cookie)
占位符_0预检结果可以缓存多长时间
占位符_0哪些响应标头是可访问的

预检的 CORS 响应示例:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

通配符与特定起源

使用 Access-Control-Allow-Origin: * 允许任何来源,但有限制:

  • 不能Access-Control-Allow-Credentials: true 一起使用
  • 只能用于公共、以太网API

对于请求请求,您必须指定目的的来源:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

如果您需要多个允许的源,服务器必须在根据白名单验证请求源后动态回显请求源。


要在跨源请求中包含cookie,客户端和服务器都必须选择加入:

客户端(JavaScript):

fetch('https://api.example.org/data', {
  credentials: 'include', // sends cookies
});

** 服务器(响应标头):**

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

如果没有 credentials: 'include',cookie 永远不会跨源发送。


CORS 常见错误及解决方案

错误信息可能的原因修复
占位符_0服务器上缺少 CORS 标头添加 Access-Control-Allow-Origin
占位符_0来源不允许列表中根据白名单验证来源
占位符_0搭载笔记本的通配符使用特定原点而不是*
占位符_0未上市的方法PUT 到添加允许的方法
占位符_0自定义标头不允许标头中将标题添加到 Access-Control-Allow-Headers

服务器配置示例

Express.js:

const cors = require('cors');
app.use(cors({
  origin: 'https://app.example.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  credentials: true,
}));

Nginx:

add_header Access-Control-Allow-Origin "https://app.example.com";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type";

##结论

CORS 是一个关键的安全层,可以保护用户,同时实现合法的跨域交互。了解简单请求和预检请求之间的、了解要配置哪些标头区别以及正确处理后台是全栈开发人员的基本技能。通过正确配置服务器的 CORS 策略,您可以在不阻止有效跨域的情况下流量维护安全性。