跨域资源共享cors

CORS: cross-origin resource sharing跨域资源共享

1.背景:浏览器为了安全,不让一个网站随便请求另一个网站的接口,而cors就是后端开"通行证",告诉浏览器这个来源可以访问我;

浏览器是如何判断请求是否跨域了呢?

浏览器有一个安全规则,叫同源策略(same-origin policy),同源就是协议+域名(非ip)+端口完全一样;只要有一个不一样就是跨域,不同源,浏览器默认禁止 AJAX/fetch 获取响应。

2.浏览器为什么要拦截跨域响应,同源策略的意义是什么,主要目的如下:

防止恶意网站:

偷偷访问你已登录的银行/公司后台

偷Cookie,Session,本地存储信息

伪造请求转账,删数据

所以跨域不是后端拦的,是浏览器拦的,后端其实已经收到请求并返回了数据,只是浏览器不交给前端JS

浏览器跨域限制的核心是‌JavaScript对跨源响应数据的读取权限‌,主要阻断‌接口请求(AJAX/Fetch)的数据获取‌,对静态资源仅限制‌内容读取与操作‌,通常不阻断加载本身;

请求发送后,若响应头缺少 Access-Control-Allow-Origin,浏览器直接丢弃响应体,JS 抛出异常

cors就是后端开"通行证",告诉浏览器这个来源可以访问我:

是一种让浏览器能安全访问不同服务器资源的技术规范;

解决什么问题‌:浏览器默认为了安全,不允许网页去请求别的域名的数据(比如 A 网站的代码不能直接拿 B 网站的数据),CORS就是用来解开这个限制的

不需要设置cors的场景:

1.前后端不分离且部署在同一域名同一端口的项目不需要设置cors;若前后端仍通过不同的端口或域名访问,此时存在跨域,需后端加响应头或网关处理(通过nginx或网关层统一转发屏蔽跨域问题);

2.前后端分离,部署在不同的域名端口,但是通过nginx或网关层统一转发请求到后端,屏蔽了跨域问题;

如果设置cors的话需要在响应头设置哪些信息呢:

核心响应头:

Access-Control-Allow-Origin:允许哪些来源访问我,必须返回

Access-Control-Allow-Methods:允许哪些请求方法,只有复杂请求(PUT/DELETE/ 自定义头)才需要。

Access-Control-Allow-Headers:允许前端带哪些自定义请求头 例如:token,Authorization

Access-Control-Allow-Credentials:是否允许带 Cookie

Access-Control-Max-Age:预检结果缓存时间,单位秒,规定时间内不再发 OPTIONS 预检请求,用于优化提升速度;

1.简单请求 vs 复杂请求:

1.1简单请求

满足下面所有条件就是简单请求:

方法:GET / HEAD / POST

请求头只有:Accept、Accept-Language、Content-Language、Content-Type

Content-Type 只能是:

application/x-www-form-urlencoded

multipart/form-data

text/plain

行为:直接发请求,不带OPTIONS预检。

1.2.复杂请求

只要有一条不符合,就是复杂请求:

PUT/DELETE/PATCH

自定义请求头(如 token、Authorization)

Content-Type: application/json

行为:先发OPTIONS预检请求 → 通过才发真实请求。

2.正常同域访问,浏览器会自动把Cookie带给后端;跨域时默认行为,浏览器不会自动带Cookie,需要设置Access-Control-Allow-Credentials 为true:

浏览器安全规范:允许携带凭证时,Origin不能是通配符 ,必须写具体域名,否则浏览器直接拒绝。

cors配置示例:

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") //对所有接口生效 
                //.allowedOriginPatterns("*")
                .allowedOriginPatterns("http://*.tb.com", "https://*.tb.com") //允许所有.tb.com子域名
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") //允许的请求方法
                .allowedHeaders("*") //允许所有请求头
                .allowCredentials(true) // 设置可以携带cookie等凭证
                .maxAge(3600); //预检请求缓存1小时
    }
}
相关推荐
DLYSB_1 小时前
《从零开始搭建机房轻量化“声光告警”系统:基于 HTTP API 与 TTS 的运维实践》
运维·网络协议·http·报警灯
华清远见成都中心17 小时前
物联网通信协议对比:MQTT、CoAP、HTTP到底该怎么选
物联网·网络协议·http
AI 小老六1 天前
Agent 工程化新底座:用 CLI 契约层打通 HTTP 接口与业务能力
网络·人工智能·http·ai·架构
努力努力再努力wz1 天前
【高性能网络库与HTTP Server系列】:基于主从 Reactor 模型实现高性能 C++ 网络库与 HTTP Server
开发语言·网络·数据结构·数据库·c++·网络协议·http
c238561 天前
HTTP 超文本传输协议全解:Web 世界的通信规则
前端·网络协议·http
念何架构之路2 天前
moby-http-api-server
网络·网络协议·http
魔尔助理顾问2 天前
HTTP Response中的CORS Headers
网络·网络协议·http
冰暮流星3 天前
flask之http请求方法
网络·网络协议·http
AlfredZhao4 天前
Linux 主机防火墙如何同时开启 80 和 443?
http·https·firewall