博客
关于我
强烈建议你试试无所不能的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

你可能感兴趣的文章
VMware 克隆的相关设置
查看>>
【转】现代浏览器的工作原理
查看>>
Exception Type: IntegrityError 数据完整性错误
查看>>
《浪潮之巅》十八十九章笔记
查看>>
Power Strings
查看>>
[转载]Hash
查看>>
Nuget:Newtonsoft.Json
查看>>
你是这样理解shell编程的嘛?
查看>>
前端性能优化之重排和重绘
查看>>
Assets和Raw区别
查看>>
【luogu4185】 [USACO18JAN]MooTube [并查集]
查看>>
手机号脱敏处理
查看>>
CI控制器调用内部方法并载入相应模板的做法
查看>>
Hdu - 1002 - A + B Problem II
查看>>
HDU - 2609 - How many
查看>>
每天CookBook之Python-003
查看>>
每天CookBook之Python-004
查看>>
Android设置Gmail邮箱
查看>>
StringBuffer的用法
查看>>
js编写时间选择框
查看>>