跨域:当协议、域名、端口号任何一个不相同时,叫称为跨域。
 
HTML5  CORS(cross-origin-resource-sharing)跨域资源共享: 原理:当需要访问跨域的资源时,可以通过定义http头信息,使得服务器响应跨域请求。
如:
// 使用通配符 * ,表示当前服务端响应任何域名发起请求,不推荐  可以具体指定某个地址
<?php header('Access-Control-Allow-Origin:*'); ?>
就这样在服务端简单加一句响应头responese headers声明,一个跨域请求就不会被浏览器的同源安全策略所阻止了! 在浏览器端通过XHR对象(IE的XDomainRequest对象),实现ajax跨域:
function corsReq(){
if(window.XMLHttpRequest)
var xhr = new XMLHttpRequest();
else if(window.XDomainRequest){
var xhr = new XDomainRequest();
}
    xhr.open('POST',url,true);  //url使用绝对路径
xhr.send(data);
xhr.close();
.....
}

浏览器检测头信息,在响应头信息中,header中包含了 Access-Control-Allow-Origin这个字段,如果字段值和我们域名相同,浏览器才会使用里面的数据做下一步处理。
(只有当目标页面的response中,包含了 Access-Control-Allow-Origin 这个header,并且它的值里有我们自己的域名时,浏览器才允许我们拿到它页面的数据进行下一步处理。)
缺点:IE10以上才支持,IE 8 ie 9通过XDomainRequest支持 

1、JSON-P跨域

什么事jsonp?

利用在页面中创建<script>节点的方法向不同域提交HTTP请求的方法称为JSONP

动态脚本注入的方法,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的

var eleScript= document.createElement("script");

eleScript.type = "text/javascript";

eleScript.src = "http://example2.com/getinfo.php";

document.getElementsByTagName("HEAD")[0].appendChild(eleScript);
 jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的(qq空间就是大量采用这种方式来实现跨域数据交换的) .JSONP是一种脚本注入(Script Injection)行为,所以也有一定的安全隐患.
JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

2、window.name跨域

indow对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。 
数据大小有限制,大小一般为2M,IE和firefox下可以大至32M左右 
有三个页面: 
a.com/app.html:应用页面。 
a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。 
b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。 
实现起来基本步骤如下:

在应用页面(a.com/app.html)中创建一个iframe,把其src指向数据页面(b.com/data.html)。 
数据页面会把数据附加到这个iframe的window.name上,data.html代码如下:

 <script type="text/javascript">

 window.name = 'I was there!'; // 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右

 // 数据格式可以自定义,如json、字符串

 </script>

在应用页面(a.com/app.html)中监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件(代理文件和应用页面在同一域下,所以可以相互通信)。app.html部分代码如下:

 
  1. <iframe src="http://gisbar.net/beta/d.html" style='display:none' frameborder="0" id="dataPage" onload ='loadFrame()'></iframe>
    
    <script type="text/javascript">

    function loadFrame(){
    var dataIframe = document.getElementById('dataPage');
    dataIframe.onload = function (){
    var data = dataIframe.contentWindow.name;
    console.log('window.name 跨域请求的数据:',data);
    }
    dataIframe.src = 'http://a.com/proxy.html';

    }

    </script>

获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)。

 
<script type="text/javascript">
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
</script>

总结起来即:iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。 
引自:http://www.cnblogs.com/rainman/archive/2011/02/21/1960044.html

 

3、HTML5中新引进的window.postMessage方法跨域

window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

调用postMessage方法的window对象是指要接收消息的那一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * 。 
缺点是IE6、IE7不支持

 在localhost页面中
<iframe src="http://gisbar.net/beta/d.html" style='display:block' frameborder="" id="msgFrame" onload ='loadMsgFrame()'></iframe>
//postMessage跨域
function loadMsgFrame(){
var msgFrame = document.getElementById('msgFrame');
msgFrame.contentWindow.postMessage('来自localhost的数据','http://gisbar.net/beta/'); //发送给指定域下的页面
}

在http://gisbar.net/beta/d.html跨域页面中:

window.onmessage = function(e){
console.log('e',e);
alert(e.data); //来自localhost的数据
}

4、iframe+document.domain来跨子域

我们只要把http://www.example.com/a.html 和 http://example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成 c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。

js跨域问题解决方案的更多相关文章

  1. js跨域及解决方案

    本文出自:http://www.cnblogs.com/oneword/archive/2012/12/03/2799443.html 1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器 ...

  2. js跨域请求解决方案

    什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 1.) 资源跳转: A链接.重定向.表单提交 2.) 资源嵌入: <link>.&l ...

  3. angular.js跨域post解决方案

    跨域,前端开发中经常遇到的问题,AngularJS实现跨域方式类似于Ajax,使用CORS机制. 下面阐述一下AngularJS中使用$http实现跨域请求数据. AngularJS XMLHttpR ...

  4. js跨域问题解释 使用jsonp或jQuery的解决方案

    js跨域及解决方案 1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题. 跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说, ...

  5. Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持

    Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持 1. 设置 document.domain为一致  推荐1 2. Apache 反向代理 推荐1 ...

  6. vue.js及H5常见跨域问题解决方案

    一.原生H5跨域问题解决方案 1.live-server 代理解决 首先在有node.js环境下,打开命令行工具,输入 npm install live-server -g 全局安装全局安装 live ...

  7. js跨域请求jsonp解决方案-最简单的小demo

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

  8. js跨域原理及解决方案

    方法一:jsonp函数 在HTML DOM中,Script标签是可以跨域访问服务器上的数据的.因此,可以指定script的src属性为跨域的url,基于script标签实现跨域.script标签本身就 ...

  9. C#进阶系列——WebApi 跨域问题解决方案:CORS

    前言:上篇总结了下WebApi的接口测试工具的使用,这篇接着来看看WebAPI的另一个常见问题:跨域问题.本篇主要从实例的角度分享下CORS解决跨域问题一些细节. WebApi系列文章 C#进阶系列— ...

随机推荐

  1. python 库之lxml安装 坑一个

    error: command 'C:\\Users\\Admin\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python ...

  2. JAVA设计模式总结之六大设计原则

    从今年的七月份开始学习设计模式到9月底,设计模式全部学完了,在学习期间,总共过了两篇:第一篇看完设计模式后,感觉只是脑子里面有印象但无法言语.于是决定在看一篇,到9月份第二篇设计模式总于看完了,这一篇 ...

  3. HDFS概述(3)————HDFS Federation

    本指南概述了HDFS Federation功能以及如何配置和管理联合集群. 当前HDFS背景 HDFS主要有两层: 1.Namespace (1)包含目录,文件和块. (2)它支持所有命名空间相关的文 ...

  4. Rectangles hdu2461容斥定理

    Rectangles Time Limit: 5000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. 【转】DSCP 与IP 优先级IP优先级

    在IPv4的报文头中,TOS字段是1字节,如下图所示.根据RFC1122的定义,IP优先级(IPPrecedence)使用最高3比特(第0-2比特).+++++++++++++++++++++++++ ...

  6. es6零基础学习之项目目录创建(一)

    和大家分享一下在学习es6的过程中所积累的东西,也希望更多的朋友能够互相学习 首先创建项目目录 打开你的命令行,什么文件下都可以,大家请随意,我自己用的git,输入 mkdir es6 创建一个完整的 ...

  7. SAP资产折旧,消息编号AA687:在上一年结算之后您只能记帐到新的一年

    问题:公司****在2015年底没有固定资产,忽略了月结的必要步骤,在2016年1-5月份一直没有计提折旧,再进行折旧时提示"在上一年结算之后您只能记帐到新的一年" 原因: sap ...

  8. Ubuntu安装Jupyter Notebook

    一.Jupyter介绍 Jupyter Notebook是一个交互式笔记本,支持运行40多种编程语言.Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享文学化程序文档,支 ...

  9. Hadoop2.0 HA集群搭建步骤

    上一次搭建的Hadoop是一个伪分布式的,这次我们做一个用于个人的Hadoop集群(希望对大家搭建集群有所帮助): 集群节点分配: Park01 Zookeeper NameNode (active) ...

  10. Pyhton编程(三)之Pycharm安装及运算符

    一:上节题目解答 1)使用while循环输出 1 2 3 4 5 6 8 9 10(注意:没有7) n=1while n<11: if n==7: pass //pass代码段指代空代码.. e ...