同源策略与跨域
同源策略限制了什么?
- 同源: 两个 URL 的协议、主机、端口号都相同;
- 限制范围: 不同源之间的资源不能随意交互;
- 具体表现:
- JS 无法读取非同源网页的 cookie、storage 与 IndexedDB;
- JS 无法读取非同源网页的 DOM;
- ajax 与 fetch 不能发送跨域请求;
- iframe 无法访问非同源 DOM;
- https 与 http 资源无法跨协议加载;
跨域请求有哪些解决方案?
- CORS: 服务端通过
Access-Control-Allow-Origin声明允许的源, 浏览器据此放行响应; - 代理: 同源页面把请求发给同源服务器, 由服务器转发到跨域目标并回传结果;
- WebSocket: 不基于 HTTP 协议, 不受同源策略限制, 可直接用于跨域通信;
预检请求在什么情况下触发?
- 触发: 浏览器在发送跨域请求之前先发
OPTIONS, 检查服务器是否允许该跨域请求; - 简单请求: 不触发预检, 需同时满足三个条件:
- 方法为
GET、POST或HEAD; - 首部字段限于
Accept-*、Content-*等规定字段; Content-Type只能是application/x-www-form-urlencoded、multipart/form-data或text/plain;
- 方法为
- 复杂请求: 违反任一约束即触发预检;
预检相关的响应字段有哪些?
| 字段 | 含义 |
|---|---|
Access-Control-Allow-Methods | 服务器允许的 HTTP 方法 |
Access-Control-Allow-Origin | 服务器允许的跨域来源 |
Access-Control-Allow-Headers | 服务器允许携带的首部字段 |
Access-Control-Max-Age | 预检结果缓存时间 |
- 缓存时间内不会再次触发预检请求;
- 跨域携带凭证的条件见 Cookie 与状态管理;