博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript 跨域
阅读量:5135 次
发布时间:2019-06-13

本文共 3386 字,大约阅读时间需要 11 分钟。

  JS跨域是指通过JS在不同的域之间进行数据传输或通信,比如用AJAX向一个不同的域请求数据,或者通过JS获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。

  不同环境下JS的通信:

URL

说明

是否允许通信

http://www.a.com/a.js

http://www.a.com/b.js

同一域名下

允许

http://www.a.com/lab/a.js

http://www.a.com/script/b.js

同一域名下不同文件夹

允许

http://www.a.com:8000/a.js

http://www.a.com/b.js

同一域名,不同端口

不允许

http://www.a.com/a.js

https://www.a.com/b.Js

同一域名,不同协议

不允许

http://www.a.com/a.js

http://70.32.92.74/b.js

域名与域名对应的IP

不允许

http://www.a.com/a.js

http://script.a.com/b.js

主域相同,子域不同

不允许

http://www.a.com/a.js

http://a.com/b.js

同一域名,不同二级域名

不允许

http://www.cnblogs.com/a.js

http://www.a.com/b.js

不同域名

不允许

  总结了一下,常见的跨域方法有一下几种:

 

1、document.domain

对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。

具体的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上document.domain = ‘a.com’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。

  http://www.a.com/a.html

document.domain = 'a.com';var ifr = document.createElement('iframe');ifr.src = 'http://script.a.com/b.html';ifr.style.display = 'none';document.body.appendChild(ifr);ifr.onload = function(){    var doc = ifr.contentDocument || ifr.contentWindow.document;    // 在这里操纵b.html,调用函数使用ifr.contentWindow.funcName    console.log(doc);};

  http://script.a.com/b.html

document.domain = 'a.com';

存在的问题:

  一、安全性,当一个站点(script.a.com)被攻击后,另一个站点(www.a.com)会引起安全漏洞。

    二、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。

 

2、动态创建script

  虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。

  根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。
 
3、JSONP(JSON with Padding)
  JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。
  在JS中,通过<script>可以在页面上引入不同域上的JS脚本文件,jsonp正是利用这个特性来实现的。
 
  前端:

  服务器端:

 

  JSONP by jQuery

jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。

$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载JS文件的形式来调用jsonp的回调函数
 
JSONP的优点是:
  它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,不需要XMLHttpRequest或ActiveX的支持。
JSONP的缺点则是:
  它只支持GET请求而不支持POST等其它类型的HTTP请求;
  它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
 
4、window.name
    window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的。
  每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
  
实现跨域需要3个文件:
  a.com/app.html:应用页面。
  a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。
  b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。
 
  
a.com/app.html

  b.com/data.html

 

特点:

  frame的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

 

5、HTML5 window.postMessage

  window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源。
  目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
 
postMessage();otherWindow.postMessage(message, targetOrigin);//otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性;//message: 所要发送的数据,string类型。//targetOrigin: 用于限制otherWindow,“*”表示不作限制

 

  a.com/index.html

  b.com/index.html

 

6、跨域资源共享(CORS)

  CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。
  CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
 
跨域方法:

注意:

  需要服务器和浏览器的支持
  例如PHP的响应页面顶端添加如下代码:
header("Access-Control-Allow-Origin:http://a.com");
  表示接受来自a.com的跨域请求,"*"表示接受所有跨域请求
 
 
总结不同跨域方法所使用的途径:

跨域方法

iframe

script

other

window.domain

   

动态<script>

 

 

JSONP

 

 

window.name

   

window.postMessage

   

CORS

   

其他跨域方法:

  1. flash (YUI IO)
  2. 代理服务器
 
 
  

转载于:https://www.cnblogs.com/dong93/p/4669965.html

你可能感兴趣的文章
解决ajax请求cors跨域问题
查看>>
Android Studio
查看>>
zz 圣诞丨太阁所有的免费算法视频资料整理
查看>>
【大数模板】C++大数类 大数模板
查看>>
【123】
查看>>
《收获,不止Oracle》pdf
查看>>
用户权限设置
查看>>
java 之equals与"=="的区别
查看>>
LinkedList<E>源码分析
查看>>
Real-Time Rendering 笔记
查看>>
如何理解HTML结构的语义化
查看>>
Intellij IDEA(eclipse设置)常用快捷键
查看>>
NAT基本原理
查看>>
Java Content Repository API 简介 转自(https://www.ibm.com/developerworks/cn/java/j-jcr/)
查看>>
visio二次开发——图纸解析
查看>>
Activity之间的跳转:
查看>>
iTunes Connect 开发者上手经验(转)
查看>>
vertical-align你为什么不生效
查看>>
C++ 实践总结
查看>>
composer 国内镜像配置
查看>>