跨域
浏览器跨源访问限制、同源策略与 CORS 放行机制的核心概念。
[!info] related notes
- 所属 MOC: 前端基础 MOC, javascript-in-browser-moc
- 上位主题: javascript-in-browser
- 相关概念: same-origin, csrf, xss-cross-site-scripting
- 面试问法: cross-origin-and-cors-interview-question
跨域
“跨域”本质上是前端口语,严格来说更接近“跨源访问受限”。
一句话定义
只要协议、域名、端口三者中有一个不同,浏览器就认为这是跨源访问,而脚本访问会受到同源策略限制。
什么叫同源
以下三者都相同,才叫同源:
- 协议
- 域名
- 端口
只要其中任意一个不同,就属于跨源。
为什么会有跨域问题
跨域问题不是 HTTP 协议本身的问题,而是浏览器出于安全考虑,对脚本跨源读取资源做了限制。
换句话说:
- 浏览器限制的是“前端脚本能不能读到结果”
- 不是说请求根本发不出去
CORS 在做什么
CORS 是一套浏览器和服务器之间的约定。
- 浏览器在跨源请求里带上
Origin - 服务器通过
Access-Control-Allow-*响应头声明是否允许访问 - 浏览器再决定要不要把响应结果交给前端代码
预检请求是什么
对于某些非简单请求,浏览器会先发一个 OPTIONS 请求确认:
- 这个源是否允许
- 这个方法是否允许
- 这些自定义请求头是否允许
确认通过后,才会继续发送真正请求。
和 Cookie 的关系
默认情况下,跨源请求不会自动带上凭证。需要客户端和服务端同时配合:
- 客户端显式开启凭证发送
- 服务端返回
Access-Control-Allow-Credentials: true - 服务端的
Access-Control-Allow-Origin不能写成*
常见误区
- 跨域不是后端接口“坏了”,而是浏览器拦截了脚本读取结果
- CORS 不是前端单方面能解决的,必须服务端配合
- 能发请求不等于前端代码就一定能拿到响应内容
最短记忆方式
跨域是浏览器限制,CORS 是服务端给浏览器的放行规则。
面试要点
来自 cross-origin-and-cors-interview-question 的面试视角整理。
一句话回答
跨域是浏览器基于同源策略对脚本跨源访问做的限制;CORS 是服务器通过响应头显式告诉浏览器“这个跨源请求可以放行”的机制,而预检请求就是浏览器在某些非简单请求前先发出的 OPTIONS 探测请求。
面试回答主线
什么叫同源
协议、域名、端口三者都相同,才叫同源。
什么叫跨域
只要这三者有一个不同,浏览器就认为是跨源访问。
CORS 在做什么
浏览器发请求时带上 Origin,服务器通过 Access-Control-Allow-* 系列头告诉浏览器是否允许访问。
这也是为什么它虽然常被前端提到,但本质上需要前后端一起讲:
- 浏览器负责拦
- 服务端负责声明是否放行
什么是预检请求
对于某些非简单请求,浏览器会先发一个 OPTIONS 请求,确认方法、头部等是否被允许,然后才决定是否发送真正请求。
常见追问
简单请求和非简单请求怎么区分
通常看请求方法、请求头和 Content-Type 是否落在浏览器定义的安全范围内。
为什么带 Cookie 时不能配 *
因为凭证请求需要更严格的源校验,Access-Control-Allow-Origin 必须是明确域名。
CORS 能不能替代鉴权
不能。
CORS 回答的是:
浏览器是否允许这个跨源脚本拿到响应。
它不回答:
调用者是不是合法用户、有没有权限访问这个接口。
所以后端仍然必须做:
- 登录态校验
- 权限校验
- 参数校验
最短记忆方式
跨域是浏览器限制,CORS 是服务器给浏览器的放行规则。