在当前的系统开发模式中,前后端分离已成为主流架构。通常,前端静态资源托管在一个域名下(如 https://psy-frontend.edu.com),而后端 API 接口则部署在另一个域名下(如 https://api.psy-backend.edu.com)。
当这套架构在浏览器中运行时,由于请求跨越了不同的源,控制台中往往会抛出经典的 CORS 拦截错误:Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy.
针对这种常见的现象,处理方式的不严谨不仅会导致功能不可用,还有可能为系统带来安全隐患。本文将讨论在 B 端系统中如何规范、安全地配置跨域资源共享。
浏览器同源策略的必要性
跨域限制本质上是浏览器提供的一种基础安全机制——同源策略(Same-Origin Policy)。
假设这种限制不存在,用户在某认证网站(如 A 站)保留了会话状态(如 Cookie),当其无意访问一个包含恶意脚本的第三方网站(B 站)时,B 站的脚本就可以直接以该用户的身份向 A 站发送数据请求,进而窃取敏感信息。
在涉及个人心理档案等高隐私数据的场景中,防范此类跨站请求伪造(CSRF)和数据窃取尤为关键。浏览器的同源策略规定了除非目标服务器显式地允许跨域调用,否则不同源之间的请求将被阻断。
避免宽泛和临时的配置方案
部分开发场景为了快速调试,可能会在服务端响应中加入 Access-Control-Allow-Origin: *。
这种配置允许任何来源的站点对后端发起请求,在生产环境中,这相当于放弃了源校验,是安全合规审查中不被允许的做法。
另外,前端项目配置中的 devServer.proxy 也是常被提及的方案。但需要注意的是,这仅适用于本地开发阶段,它通过本地 Node.js 服务器代理请求绕过了浏览器的限制。项目打包发布到生产环境后,该配置将失效,客户端仍会受到 CORS 规则的约束。
网关层的统一控制与白名单配置
在橙星云的架构规范体系中,跨域规则的配置应当与业务代码解耦,推荐在系统的最外层网关(如 Nginx)进行统一的流量接管和权限收拢。
通过 Nginx 的配置,可以实现基于正则匹配的白名单机制,严格控制哪些域名拥有访问接口的权限。
“`nginx
server {
listen 80;
server_name api.psy-backend.edu.com;
location / {
建立白名单变量
set $cors_origin "";
if ($http_origin ~* "^https://(psy-frontend\.edu\.com|test\.psy-frontend\.com)$") {
set $corsorigin $httporigin;
}
注入标准 CORS 响应头
addheader Access-Control-Allow-Origin $corsorigin always;
add_header Access-Control-Allow-Methods ‘GET, POST, PUT, DELETE, OPTIONS’ always;
add_header Access-Control-Allow-Credentials ‘true’ always;
预检请求(Preflight)缓存优化
add_header Access-Control-Max-Age 7200 always;
if ($request_method = ‘OPTIONS’) {
add_header Access-Control-Allow-Headers ‘Authorization, Content-Type, X-Requested-With’ always;
return 204;
}
转发至后端业务集群
proxypass http://backendcluster;
}
}
“`
通过上述配置,系统能够对合法的调用方发放许可,而对未授权域名的请求则不返回 CORS 头,从而利用浏览器的安全机制阻断非法访问。
与此同时,对于复杂的跨域请求,浏览器通常会发送 OPTIONS 预检请求。通过设置 Access-Control-Max-Age,可以将预检结果在客户端缓存,减少每次正式请求前的额外通信开销。这种在网关层进行集中的安全拦截与缓存优化,既维护了数据的安全性,又兼顾了接口的响应效率。
