js跨域问题的三种解决方案,js解决跨域的三种方法

js跨域问题的三种解决方案,js解决跨域的三种方法,js前端解决跨域问题的8种方案(最新最全)

本文主要讲一下前端跨域问题的几种解决方案。现在我把它们分享给你,给你一个参考。来和边肖一起看看吧。

1.相应的策略如下:

统一资源定位器

解释

允许交流?

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

相同的域名,不同的二级域名(同上)

否(在这种情况下不允许访问cookie)

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

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

不同的域名

不允许

特别注意两点:

第一,如果“前台”对协议和端口引起的跨域问题无能为力,

其次,在跨域问题上,只通过“URL头”来识别域,而不去尝试判断同一个ip地址对应两个域还是两个域在同一个ip上。

“URL的头”指的是window . location . protocol window . location . host,也可以理解为“域、协议、端口必须匹配”。

2. 前端解决跨域问题

1 document.domain + iframe (只有在主域相同的时候才能使用该方法)

1)在www.a.com/a.html:

document . domain= a . com ;

var IFR=document . createelement( iframe );

IFR . src= http://www . script . a . com/b . html ;

ifr.display=none

document . body . appendchild(IFR);

ifr.onload=function(){

var doc=IFR . content document | | IFR . content window . document;

//这里操作doc,也就是b.html

ifr.onload=null

};

2)在www.script.a.com/b.html:

document . domain= a . com ;

2 动态创建script

这个没什么好说的,因为脚本标签不受同源策略的限制。

函数loadScript(url,func) {

var head=document . head | | document . getelementbytagname( head )[0];

var script=document . createelement( script );

script.src=url

script . onl oad=script . onreadystatechange=function(){

如果(!this . ready state | | this . ready state== loaded | | this . ready state== complete ){

func();

script . onl oad=script . onreadystatechange=null;

}

};

head.insertBefore(脚本,0);

}

window.baidu={

sug:函数(数据){

console.log(数据);

}

}

loadScript( http://suggestion . Baidu . com/su?wd=w ,function(){ console . log( loaded )});

//我们请求的内容在哪里?

//我们可以在chorme调试面板的源码中看到脚本引入的内容。

3 location.hash + iframe

原理是使用location.hash来传递值。

假设域名为a.com的文件cs1.html想要与域名为cnblogs.com的cs2.html交流信息。

1)cs1.html首先自动创建一个隐藏的iframe,iframe的src指向cnblogs.com域名下的cs2.html页面。

2)在cs2.html响应请求后,它将通过修改cs1.html的哈希值来传递数据。

3)同时在cs1.html中加入一个定时器,每隔一段时间判断location.hash的值是否有变化,一旦有变化,就获取hash值。

注意:由于两个页面不在同一个域中,IE和Chrome不允许修改parent.location.hash的值,所以我们不得不求助于a.com域名下的代理iframe。

代码如下:

第一,a.com下的文件,cs1.html文件:

函数startRequest(){

var IFR=document . createelement( iframe );

IFR . style . display= none ;

IFR . src= http://www . cn blogs . com/lab/cscript/cs2 . html # paramdo ;

document . body . appendchild(IFR);

}

函数checkHash() {

尝试{

var data=location.hash?location . hash . substring(1):“”;

if (console.log) {

console.log(现在数据是数据);

}

} catch(e){ };

}

setInterval(checkHash,2000);

cnblogs.com域名下的Cs2.html:

//模拟一个简单的参数处理操作

开关(location.hash){

案例#paramdo :

回调();

打破;

案例#paramset :

//做点什么……

打破;

}

函数回调(){

尝试{

父母。位置。hash=一些数据;

} catch (e) {

//ie、chrome的安全机制无法修改parent.location.hash,

//所以要利用一个中间的cnblogs域下的代理内联框架

var IFR proxy=文档。createelement(“iframe”);

IFR代理。风格。display= none

IFR代理。src= http://a . com/test/cscript/CS3。html # somedata ;//注意该文件在a.com的域下

文档。身体。appendchild(IFR代理);

}

}

a.com下的域名cs3.html

//因为父母父母和自身属于同一个域,所以可以改变其位置。哈希的值

父母。父母。位置。哈希=自我。位置。哈希。子串(1);

4 window.name + iframe

窗口。名称的美妙之处:名称值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的名字值(2MB)。

1) 创建a.com/cs1.html

2) 创建a.com/proxy.html,并加入如下代码

脚本

函数代理(url,func){

var isFirst=true,

IFR=文件createelement(“iframe”),

loadFunc=function(){

if(isFirst){

IFR。内容窗口。地点=http://a.com/cs1.html;

isFirst=false

}否则{

func(IFR。内容窗口。姓名);

ifr.contentWindow.close().

文档。身体。移除子项(IFR);

IFR。src=

ifr=null

}

};

ifr.src=url

IFR。风格。display= none

如果(IFR。附加事件)IFR。附加事件(“onload”,load func);

else ifr.onload=loadFunc

文档。身体。appendchild(iframe);

}

/脚本

/头

身体

脚本

代理(‘http://www.baidu.com/,函数(数据){

console.log(数据);

});

/脚本

/body

3在b.com/cs1.html中包含:

脚本

window.name=要传送的内容;

/脚本

5 postMessage(HTML5中的XMLHttpRequest Level 2中的API)

1)a.com/index.html中的代码:

iframe id= IFR src= b . com/index。html /iframe

脚本类型=文本/javascript

window.onload=function() {

var IFR=文档。getelementbyid( IFR );

var target origin= http://b . com//若写成http://b.com/c/proxy.html的效果一样

//若写成http://c.com的就不会执行邮件了

ifr.contentWindow.postMessage(我在那儿!,目标原点);

};

/脚本

2)b.com/index.html中的代码:

脚本类型=文本/javascript

窗户。addevent侦听器(消息,函数(事件){

//通过起源属性判断消息来源地址

如果(事件。origin== http://a . com ){

警报(事件。数据);//弹出"我在那里!"

警报(事件。来源);//对a.com、index.html中窗户对象的引用

//但由于同源策略,这里事件。来源不可以访问窗户对象

}

},假);

/脚本

6 CORS

克-奥二氏分级量表背后的思想,就是使用自定义的超文本传送协议头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。

工业管理学(工业工程)中对克-奥二氏分级量表的实现是极速数据率

var XDR=new XDomainRequest();

xdr.onload=function(){

控制台。日志(XDR。responsetext);

}

xdr.open(get , http://www .百度一下。com’);

.

xdr.send(空);

其它浏览器中的实现就在xhr中

var xhr=new XMLHttpRequest();

xhr。onreadystatechange=function(){

if(xhr.readyState==4){

if(xhr。状态=200 xhr。状态304 | | xhr。状态==304){

控制台。日志(xhr。responsetext);

}

}

}

xhr.open(get , http://www .百度一下。com’);

.

xhr.send(空);

实现跨浏览器的克-奥二氏分级量表

函数createCORS(方法,网址){

var xhr=new XMLHttpRequest();

if(xhr中的"带凭据"){

xhr.open(方法,网址,真);

}else if(typeof XDomainRequest!=未定义){

var xhr=new XDomainRequest();

xhr.open(方法,网址);

}否则{

xhr=null

}

返回xhr

}

var request=createCORS(get , http://www .百度一下。com’);

如果(请求){

request.onload=function(){

.

};

请求。send();

}

7 JSONP

JSONP包含两部分:回调函数和数据。

回调函数是当响应到来时要放在当前页面被调用的函数。

数据就是传入回调函数中的json数据,也就是回调函数的参数了。

函数handleResponse(响应){

console.log(响应的数据是: response . data );

}

var script=document . createelement( script );

script . src= http://www . Baidu . com/JSON/?callback=handle response ;

document . body . insert before(script,document . body . first child);

/* handleResonse({ data : zhe })*/

//原理如下:

//当我们通过脚本标签请求时

//后台会跟随相应的参数(json,handleResponse)

//生成相应的json数据(handle response({ data: zhe }))

//最后,这个返回的json数据(代码)会放在当前的js文件中执行。

//至此,跨域通信完成。

jsonp虽然很简单,但是有如下缺点:

1)安全问题(请求代码可能存在安全风险)

2)不容易确定jsonp请求是否失败。

8个网络插座

Web sockets是一个浏览器API,它的目标是在单个持久连接上提供全双工和双向通信。(同源策略不适用于web套接字)

WebSockets原理:JS创建web sockets后,会向浏览器发送一个HTTP请求来发起连接。得到服务器的响应后,建立的连接将使用HTTP upgrade从HTTP协议交换到web sockt协议。

它只能在支持web socket协议的服务器上工作。

var socket=new WebSockt( ws://www . Baidu . com );//http-ws;https-wss

socket . send( hello WebSockt );

socket . on message=function(event){

var data=event.data

}

原文链接:http://blog.csdn.net/joyhen/article/details/21631833

这就是本文的全部内容。希望对大家的学习有帮助,支持我们。

js跨域问题的三种解决方案,js解决跨域的三种方法