JS 跨域
JS 跨域是指通过 JS 在不同的域之间进行数据传输或通信,比如用 Ajax 向一个不同的域请求数据,或者通过 JS 获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
同源策略
同源策略是浏览器的一种安全策略,所谓同源是指域名,协议,端口号完全相同。
- 目的
- 保护用户信息安全
- 假如你的支付宝已经登录了,域名是
a.com,有一个黑客在自己的页面上(域名是b.com)写了一段让你向他的支付宝转账的脚本,如果没有浏览器同源策略,后果无法想象!!!
- 限制
- cookie、localStorage、IndexDB无法读取
- 无法操作跨域的 iframe 里面的 DOM 元素
- Ajax 请求无法发送
何为跨域
不同源则为跨域,假设当前域名是 http://www.example.com/detail.html ,其中 com 是顶级域名, example 是一级域名, www 是特殊的二级域名。
1 | http://api.example.com/detail.html 不同源 域名不同 |
为什么不能跨域?
出于安全考虑,浏览器禁止跨域访问。
跨域的方式
目前主流跨域方式有以下几种:
- jsonp
- cors
- 降域
- postMessage
- 后端代理
jsonp 跨域访问了,还安全吗?
安全不安全是对于服务器而言,你发送了 callback 参数,服务器不返回也就没有了作用, jsonp 是浏览器与服务器双方配合才能实现。所以是安全的。
jsonp 跨域原理
在 js 中,我们直接用 XMLHttpRequest 请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的 js 脚本文件却是可以的, jsonp 正是利用这个特性来实现的。
比如,我们有个 index.html 页面,它内部需要通过 Ajax 获取不同域上的 json 数据,假设这个 json 数据的服务器地址是 http://example.com/json.php ,那么 index.html 中的代码可以这样写:
1 | <script> |
我们可以看到获取数据的地址后面有一个 callback 参数,这个参数可以修改,但是必须保证与请求服务器接口的 callback 参数一致,以便服务器正确解析。如果获取数据的服务器接口不是你自己控制的,就必须按照提供数据的那一方的规定格式来操作,一般习惯都是 callback 。
因为获取数据的地址被当做一个 js 文件引入,所以必须返回一个能执行的 js 文件,所以 json.php 代码可能是这样的:
1 |
|
最终 index.html 页面输出结果为:
getData({"name": "xiaoming", "age": 10})
所以通过 http://example.com/json.php?callback=getData 得到的 js 文件,就是我们之前定义的 getData 函数,并且它的参数就是我们需要的 json 数据,这样我们就跨域获得了我们需要的数据。
简单来说, jsonp 的原理就是通过 script 标签引入一个 js 文件,这个 js 文件载入成功后会执行我们在 url 参数中指定的函数,并且会把我们需要的 json 数据作为参数传入。所以 jsonp 是需要服务器端的页面进行相应的配合的。