公司的桌面版运用了 iframe 在取数据方面遇到不少坑,周末空闲把知识点整理下。
什么是跨域
JavaScript对安全访问因素的考虑,是不允许js跨域调用其他页面,具体分为以下几类:
不同域名
相同域名不同端口号,如 https://www.baidu.com:8000 和 https://www.baidu.com:8088
同一个域名不同协议,如 https://www.baidu.com 和 http://www.baidu.com
域名和域名对应的的IP,如 http://www.baidu.com:8000 和 http://119.75.217.109
主域和子域,如 http://www.baidu.com 和 https://test.baidu.com
解决方案
- JSONP
JSONP 和 JSONP?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)–百度
实际是利用了 <script> 标签的 src 属性并不被同源策略所约束,其实所有的 src 属性的标签都是不被同源策略所约束。
1 | // html |
这种方案需要注意的是他支持GET这一种HTTP请求类型,还有就是其他域要有一定可靠性。
- 跨域资源共享(CORS-Cross Origin Resource Sharing)
CORS 它是JSONP模式的现代升级版,CORS 定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求与JSONP不同的是,CORS除了GET要求方法以外也支持其他的 HTTP要求。浏览器CORS请求分成两种。
- 请求方式
GET
HEAD
POST - HTTP的头信息子段
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain,其中’text/plain’默认支持,其他两种则需要预检请求和服务器协商。
满足以上两大点的即为简单请求,否则为非简单请求
注:个人认为除了 cors 之外的跨域解决方案 都是耍流氓
- document.domain + iframe(适用于跨子域的交互)
只需要在A.htm与B.htm里都加上一句document.domain = ‘xxx.com’,两个页面就有了互信的基础,而能无碍的交互。
- window.name + iframe
类似在 a 页面(a.com/app.html)中创建一个iframe,把其src指向 b 页面(b.com/data.html),数据页面会把数据附加到这个iframe的window.name上。
- HTML5中的postMessage(适用于两个iframe或两个页面之间)
postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
eg:
1 | window.onload=function(){ |
postMessage(data,origin)方法接受两个参数:
data要传递的数据,html5 规范中提到该参数可以是 JavaScript 的任意基本类型或可复制的对象,但是为了兼容性在传递参数的时候需要使用 JSON.stringify() 方法对对象参数序列化。origin字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,只会将message传递给指定窗口.