素材巴巴 > 程序开发 >

跨域的请求数据

程序开发 2023-09-14 18:12:35

一.域的限制

域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。 有一种简明的说法来解释广域跨域:跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。由于安全原因,跨域访问是被各大浏览器所默认禁止的。

在广域网环境中,由于浏览器的安全限制,网络连接的跨域访问时不被允许的,XmlHttpRequest也不例外。但有时候跨域访问资源是必需的。

同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。同源策略不阻止将动态脚本元素插入文档中。

参考理论一:在浏览器中不能直接来跨域访问,而在服务器端没有跨域安全限制。

这样的话,可以在服务端完成跨域访问,而在客户端来取得结果就可以了。

参考理论二:同源策略不阻止动态脚本元素插入,脚本访问可以跨域。

用服务器端的XmlHttpRequest代理实现跨域访问

我们不能在浏览器端直接使用AJAX来跨域访问资源,但是在服务器端是没有这种跨域安全限制的。所以,我们只需要让服务器端帮我们完成“跨域访问”的工作,然后在浏览器端用AJAX获取服务器端“跨域访问”的结果就可以了。这就是所谓的在服务器端创建一个XmlHttpRequest代理,通过这个代理来访问其他域名下的资源。这里引用Yahoo! JavaScript Developer Center上的几张图来进一步说明这个方案:

使用XmlHttpRequest访问同一域名下的资源:

使用XmlHttpRequest跨域访问资源:

用服务器端的XmlHttpRequest代理来跨域访问资源:

编写服务器端XmlHttpRequest代理的具体过程就不赘述了,无非是创建一个自定义的HTTP请求。

用动态script标签实现客户端的跨域访问

很明显,上一个方案必须要在服务器端做相应的改动才能实现跨域访问。但是有些时候,用户不能改动服务器端的源代码,而且更多的时候,用户并没有Web开发的基础,他们只会简单的复制、粘贴操作。这个时候,第一个方案就不能满足一个服务提供者的需求了。

我们应该能注意到,虽然浏览器有跨域访问的限制,但是我们是可以通过script标签远程引用其他域名下的脚本文件的。而且,script标签的 src属性不一定必须是一个存在的js文件,也可以是一个http handler的url,只要这个http handler返回的是一个text/javascript类型的响应就可以了。

这样,我们的第二个方案就浮出水面了。只要让用户添加一个script标签,这个script标签的src属性指向我们api的url,并提供 api需要的一些参数,通常其中包括了一个作为callback的js函数名。针对这个脚本请求,我们服务器端的http handler会根据url中携带的参数,生成并返回相应的脚本,通常这个脚本的内容是调用callback函数,并传入用户需要的数据作为参数。于是,一个跨域访问的过程就完成了。下面是一个Yahoo! JavaScript Developer Center上提供的一个例子:

01 02 03 How Many Pictures Of Madonna Do We Have? 04 10 11 12 13 14

将这段代码复制到文本编辑器中,另存为xxx.html,再将另存到文件拖到浏览器中,就能看到效果了(网速慢的话需要等待一下)。在这个例子中,api的url的callback参数指定了跨域访问成功后会调用的函数的名称,这个函数有一个参数,这个参数就是用户跨域访问需要的数据,通常是一个json对象。

这个例子有一个不足之处,就是这个跨域访问实际上是“静态的”,也就是说不能随时动态的实现跨域访问,例如同一个按钮点击事件来触发跨域访问。其实只要将代码稍微修改一下,就可以实现动态的跨域访问了,下面是修改后的代码:

01 02 03 How Many Pictures Of Madonna Do We Have? 04 18 19 20 "button" value="click me!" onclick="onClick()"> 21 22

服务器端的http handler处理请求的过程这里也不赘述了,关键就是根据用户的参数生成js代码。

其他实现跨域访问的方案

除了上面两种方案之外,还有其他一下方法同样可以实现跨域访问,例如:

Javascript跨域和Ajax跨域解决方案

Ajax跨域和JS的跨域通信(Cross The Site)的几种解决方案

最近做的一个项目中需要ajax跨域取得数据,如果是在本域中确实没有问题,但是放到二级域和其他域下浏览器直接就弹出提示框:“该页正在访问其控制范围之外的数据,这有些危险,是否继续"。

什么引起了ajax跨域不能的问题?ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告。

有什么完美的解决方案么?没有。解决方案有不少,但是只能是根据自己的实际情况来选择。

具体情况有:

解决方法:

总结:


  二.跨域请求解决方法

怎么算跨域?

在明确了跨域的概念之后,我们需要明白在什么情况下属于跨域。再摘录另一篇文章《JavaScript跨域总结与解决办法》如下:
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 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问) http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许

跨域如何解决?

在这里我们主要探讨在移动端上的跨域问题,主要有以下两种解决办法:
1.JSONP 关于JSONP在这里不做过多说明,其原理主要就是通过前面所说的脚本元素来绕过浏览器的跨域限制,大家想了解的可以看看这篇文章《说说JSON和JSONP》。
2.框架设置 在这里需要说明一个问题,其实在移动端的WebView并不存在跨域问题,因为WebView是通过file://协议来加载html文件的,而file://协议各个浏览器的实现标准不一样,有些浏览器如移动端的WebView、IE并没有限制对file协议的跨域访问。
但是我们在Android上使用PhoneGap+jQuery Mobile的时候仍然不能直接进行跨域访问,这是为什么呢?这其实是因为基于安全的考虑,PhoneGap和jQuery本身对跨域访问进行了限制,我们需要对它们进行一些配置。
在PhoneGap上,需要在项目的Configure文件中加入,或者把*替换为所要访问的域名,这就允许了对该域名进行跨域访问。在jQuery上,我们需要在mobileInit函数中加上以下两行代码来允许跨域访问: [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
  1. $.support.cors = true;  
  2. $.mobile.allowCrossDomainPages = true;  

但是当我们需要在pc上对html5代码进行调试时应该怎么办呢?在这里以Chrome为例,可以关闭浏览器的跨域限制。在终端中通过以下命令启动Chrome浏览器即可:
Windows:
chrome.exe --disable-web-security

MacOS:
/usr/bin/open -a "/Applications/Google Chrome.app" --args --disable-web-security


标签:

上一篇: angularJs之template指令 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。