宝哥软件园

详细说明ajax跨域问题的解决方案

编辑:宝哥软件园 来源:互联网 时间:2021-09-04

今天,让我们记录一些关于ajax跨域的问题。未雨绸缪。

跨域

相应的政策限制

同源策略防止加载在一个域上的脚本获取或操作另一个域上的文档属性。也就是说,请求的网址的域必须与当前网页的域相同。这意味着浏览器隔离不同来源的内容,以防止它们之间的操作。

解决方法

一般来说,有两种常见的方式,一种是从服务器端,另一种是从客户端。两者各有利弊,具体用哪种方法需要具体分析。

服务器设置响应头。服务器代理客户端采用脚本回调机制。模式1

访问控制允许源关键字只有在服务器端设置时才会生效。也就是说,即使客户端再次使用,

xmlhttprequest . setheaderrequest(' xx ',' xx ');不会有什么影响。

普通ajax请求

让我们模拟ajax非跨域请求的案例实现。

test1.html

!doctype html lang=' en ' head meta charset=' utf-8 ' title AJax test/title/head dyinput type=' button ' value=' test ' onclick=' crossdomainrequest()' div id=' content '/div script var xhr=new xmlhttprequest();var URL=' http://localhost/learn/Ajax/test1 . PHP ';函数crossDomainRequest(){ document . getelementbyid(' content ')。innerHTML='font color='red '正在加载./font ';//延迟settimeout(函数(){if (xhr) {xhr.open ('get ',URL,true)的执行;xhr . onreadystatechange=handle _ response;xhr . send(null);} else { document . getelementbyid(' content ')。innertext=“无法创建XMLHttpRequest对象”;} }, 3000);} function handle _ response(){ var container=document . getelementbyid(' content ');if(xhr . readystate==4){ if(xhr . status==200 | | xhr . status==304){ container . innerhtml=xhr . responsetext;} else {container.innerText='无法跨域请求';}}}/script/body/htmltest1。同级别目录下的PHP如下:

?“有用。”;正常ajax请求

跨域请求

刚才HTML文件和php文件都在Apache容器下,不存在跨域的情况。现在把HTML文件放在桌面上,那么如果你再次请求PHP数据,你会创建这样一个“跨域请求”。

注意浏览器的地址栏信息

当您再次访问时,您会发现以下错误消息。

跨域出现了问题

针对这种情况,常见的操作是设置访问控制允许来源。

格式:访问控制-允许-来源: domain.com/xx/yy.*

如果您知道客户端的域名或请求的固定路径,最好不要使用通配符来进一步确保安全性。如果您不确定,请使用通配符*。

当后端开发语言是PHP时,您可以在文件的开头进行设置:

标头('访问控制-允许-原始: * ');如果是ASPX页面,就这样设置(Java和它类似):

回应。AddHeader('访问控制-允许-来源',' * ');这时,再参观一下刚才的小路。

服务器端跨域设置

服务器代理模式

这种方式应该算是比较常见且被广泛采用的一种方式。说代理实际上是一个信息,有点言过其实了。让我们举一个小例子:

小明喜欢三班一个叫小红的女生,却不好意思要QQ和微信号。然后我问小兰,我班上的一个女生。你自己来要吧。所以,小兰相当于一个代理人。帮小明获取小红无法直接获取的联系方式。

让我们举个例子来说明这个问题。

直接跨域请求

修改刚才的URL,让ajax直接请求其他网站的数据。

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 ' title Ajax测试/title/head dyinput type=' button ' value=' Test ' onclick=' crossDomainRequest()' div id=' content '/div脚本var xhr=new XMLHttpRequest();//var URL=' http://localhost/learn/Ajax/test1。PHP ';var URL=' http://API。清云阁。com/API。PHP?key=freeappid=0msg=哒哒;函数crossDomainRequest(){ document。getelementbyid(' content ').innerHTML='font color='red '正在加载./font ';//延迟执行setTimeout(function(){ if(xhr){ xhr。open(' GEt ',url,true);xhr。onreadystatechange=handle _ response;xhr。发送(null);} else { document。getelementbyid(' content ').' innerText='不能创建XMLHttpRequest对象;} }, 3000);}函数handle _ response(){ var container=document。getelementbyid(' content ');if(xhr。readystate==4){ if(xhr。status==200 | | xhr。status==304){ container。innerhtml=xhr。responsetext} else { container.innerText='不能跨域请求;} } }/脚本/正文/html结果如下:

代理模式下直接跨域会失败

启用代理模式

刚才的超文本标记语言页面,咱们还是用自己的接口:

URL=' http://localhost/learn/Ajax/test1。PHP ';具体如下:

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 ' title Ajax测试/title/head dyinput type=' button ' value=' Test ' onclick=' crossDomainRequest()' div id=' content '/div脚本var xhr=new XMLHttpRequest();var URL=' http://localhost/learn/Ajax/test1。PHP ';//var URL=' http://API。清云阁。com/API。PHP?key=freeappid=0msg=哒哒;函数crossDomainRequest(){ document。getelementbyid(' content ').innerHTML='font color='red '正在加载./font ';//延迟执行setTimeout(function(){ if(xhr){ xhr。open(' GEt ',url,true);xhr。onreadystatechange=handle _ response;xhr。发送(null);} else { document。getelementbyid(' content ').' innerText='不能创建XMLHttpRequest对象;} }, 3000);}函数handle _ response(){ var container=document。getelementbyid(' content ');if(xhr。readystate==4){ if(xhr。status==200 | | xhr。status==304){ container。innerhtml=xhr。responsetext} else { container.innerText='不能跨域请求;} } }/脚本/正文/html然后对应的test1.php应该帮助我们实现数据请求这个过程,把"小红的联系方式"要到手,并返回给"小明"。

?PHP $ URL='http://api.qingyunke.com/api.php?key=freeappid=0msg=hello world .$ result=file _ get _ contents($ URL);回声$结果;下面看下代码执行的结果。

代理模式下的跨域实现

jsonp方式

带填充的JSON灵感其实源于在超文本标记语言页面中脚本标签内容的加载,对于脚本的科学研究委员会属性对应的内容,浏览器总是会对其进行加载。于是:

克服该限制更理想方法是在网页面中插入动态脚本元素,该页面源指向其他域中的服务统一资源定位器并且在自身脚本中获取数据。脚本加载时它开始执行。该方法是可行的,因为同源策略不阻止动态脚本插入,并且将脚本看作是从提供网页面的域上加载的。但如果该脚本尝试从另一个域上加载文档,就不会成功。

实现的思路就是:

在服务器端组装出客户端预置好的json数据,通过回调的方式传回给客户端。

原生实现

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 ' title Ajax测试/title脚本src=' http :http://Ajax。aspnetcdn。com/Ajax/jquery/jquery-1。8 .0 .js ' type=' text/JavaScript '/script/headly输入类型=' text ' name=' talk ' id=' talk '输入类型=' button '值=' Test ' id=' BTN ' div id=' content '/div script类型=' text/JavaScript '函数JSON回调(结果){ for(var I in} } var JSONP=document。create element(' script ');JSONP。type=' text/JavaScript ';JSONP。src=' http://localhost/learn/Ajax/test1。PHP?callback=jsoncallback ';文件。getelementsbytagname(' head ')[0].appendChild(JSONP);/脚本/正文/html服务器端test1.php内容如下:

?php$arr=[1,2,3,4,5,6];$ result=JSON _ encode($ arr);echo ' jsonpcallback('。$结果。')';要注意最终组装的返回值内容。

让我们看看最终的代码执行效果。

JSONP原生跨域实现

JQuery模式下的实现

使用原生JavaScript时还有很多事情要处理。为了简化操作,我们决定改用jQuery。

!doctype html lang=' en ' head meta charset=' utf-8 ' title Ajax Test/title script src=' http :http://ajax.aspnetcdn.com/Ajax/jquery/jquery-1 . 8 . 0 . js ' type=' text/JavaScript '/script/head mdy input type=' text ' name=' talk ' id=' talk ' input type=' button ' value=' Test ' id=' BTN ' div id=' content '/div script type=' text/JavaScript ' function _ late$('#content ')。追加(元素);} $('#btn ')。click(function(){//alert($(' # talk '))。val());$.Ajax({ URL : ' http://localhost/learn/Ajax/test1 . PHP ',method: 'post ',dataType: 'jsonp ',data: {'talk': $('#talk ')。val()},jsonp: 'callback ',success:函数(callback){ console . log(callback . content);late _ action(callback . content);},error:函数(err){ console . log(JSON . stringify(err));}, });});/script/body/html相应的,test1.php也做了一些改动,以满足客户端聊天的需求。

?php$requestparam=isset($_GET['回调'])?$_GET['回调']: '回调';//Qing云志聊天机器人界面:http://api.qingyunke.com/api.php? Key=freeappid=0msg=hello//从客户端接收请求内容$ talk=$ _ REQUEST[' talk '];$ result=file _ get _ contents(' http://API . qingyunke.com/API . PHP?key=free appid=0msg=$ talk’);//拼接一些字符串回显$requestparam。($ result)';最后,我们来看看跨域效应。

JSONP  跨域实现聊天应用

摘要

至此,简单的ajax跨域问题几乎解决了。个人对这三种方式有一点自己的看法。

服务器设置访问控制允许来源的方式,适用于信用较高的小型应用或个人应用。代理模式更适合大规模应用。但是需要一个统一的标准,这样更便于管理和维护。JSONP模式感觉相当乏味(我可能没有足够的经验,也没有意识到这种模式的优势(﹏)b).自己玩就知道有这么一回事。保养真的是一个优点,也是一个麻烦。参考链接:

Ajax跨域请求://www . JB 51 . net/article/72703 . htm

服务器端跨域设置://www . JB 51 . net/article/104442 . htm

高级Ajax说明://www . JB 51 . net/article/116878 . htm

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

更多资讯
游戏推荐
更多+