跨域草稿
# 什么是跨域
同源:协议、主机和端口均相同的组合的网站视为 「同源」,否则视为「跨源」(也叫跨域)。
# 区别于同站
顶级域 (TLD),例如 .com
和 .org
,维护在根区数据库 (opens new window) 中。
但是对于 .com.cn
和 .github.io
等域,仅用 .cn
或者 .io
是不足以识别站点的,因此又定义了 eTLD 概念,以上两个域就属于 eTLD。
可以从这个网站 (opens new window)查看 eTLD 列表。
eTLD+1 相同的网站被视为「同站」,否则称为「跨站」
# 解决跨域的几种方案
- cors
- jsonp
- postMessage
- websocket
- ...
# jsonp
比如调用天气接口,正常 ajax 访问跨域url 是不行的,
主要是利用 script 标签可以跨域的原理
我们往 script url 上加上回调函数名和请求参数时
回调函数参数是约定值,不一定是 cb 也可以是 callback 看服务端是怎么处理的 在提供参数后,服务端做了处理,后面返回一个可执行的js代码,一般是把响应结果放入回调函数中 比如url = xxxx?cb=test&userId=1
jsonp 可以返回这样一段代码
test({name:"xx",age:18})
缺点就是只支持 get
# cors
服务端设置 Access-Control-Allow-Origin:*
or 具体域名
若要带 cookie (跨域请求接口所在域的 cookie),需要:
- 前端设置 xhr.withCredentials = true
- 后端返回 Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin
必须为具体域名
# 简单请求
根据请求方法和请求头字段判断是否为简单请求
简单请求的话浏览器直接发跨域请求,否则的话得看服务端支不支持,会先发个预检请求,
带上 Access-Control-Request-Method (实际请求将用的方法)和 Access-Control-Request-Headers(实际请求将带的自定义头部)
服务端返回自己支持的请求方法和请求头
Access-Control-Allow-Methods 和 Access-Control-Allow-Headers 可以避免多次预检请求
如果我们发起的请求满足条件的话,则可发起跨域请求
预检请求可以被缓存,下次访问相同请求(包括url参数)时,预检请求还在缓存就不会发起
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
# postMessage
允许非同源之间窗口的通信
# 加代理
# websocket
WebSocket 使用上需要指定访问地址,所以肯定是可以跨域的