AJAX跨域访问解决方案
Case I. Web代理的方式 (on Server A)
即用户访问A网站时所产生的对B网站的跨域访问请求均提交到A网站的指定页面,由该页面代替用户页面完成交互,从而返回合适的结果。此方案可以解决现阶段所能够想到的多数跨域访问问题,但要求A网站提供Web代理的支持,因此A网站与B网站之间必须是紧密协作的,且每次交互过程,A网站的服务器负担增加,且无法代用户保存session状态。
Case II. on-Demand方式 (on Server A)
MYMSN的门户就用的这种方式,不过 MYMSN中不涉及跨域访问问题。在页面内动态生成新的<script>,将其src属性指向别的网站的网址,这个网址返回的内容必须是合法的Javascript脚本,常用的是JSON消息。此方案存在的缺陷是, script的src属性完成该调用时采取的方式时get方式,如果请求时传递的字符串过大时,可能会无法正常运行。不过此方案非常适合聚合类门户使用。
1: <html>
2: <head>
3: <script>
1:
2: function loadContent()
3: {
4: var s=document.createElement('SCRIPT');
5: s.src='http://www.anotherdomain.com/TestCrossJS.aspx?f=setDivContent';
6: document.body.appendChild(s);
7: }
8: function setDivContent(v)
9: {
10: var dv = document.getElementById("dv");
11: dv.innerHTML = v;
12: }
</script>
4: </head>
5: <body>
6: <div></div>
7:
8: <input value="Click Me">
9: </body>
10: </html>
11: //其中的www.anotherdomain.com/TestCrossJS.aspx是这样的,
12: <script runat="server">
1:
2: void Page_Load(object sender, EventArgs e)
3: {
4: string f = Request.QueryString["f"];
5: Response.Clear();
6: Response.ContentType = "application/x-javascript";
7: Response.Write(String.Format(@"
8: {0}('{1}');",
9: f,
10: DateTime.Now));
11: Response.End();
12: }
</script>
点击“Click Me”按钮,生成一个新的script tag,下载对应的 Javascript 脚本,结束时回调其中的setDivContent(),从而更新网页上一个div的内容。
Case III. iframe方式 (on Server A)
查看过醒来在javaeye上的一篇关于跨域访问的帖子,他提到自己已经用iframe的方式解决了跨域访问问题。数据提交跟获取,采用iframe这种方式的确可以了,但由于父窗口与子窗口之间不能交互(跨域访问的情况下,这种交互被拒绝),因此无法完成对父窗口效果的影响。
在页面内嵌或动态生成指向别的网站的IFRAME,然后这2个网页间可以通过改变对方的anchor hash fragment来传输消息。改变一个网页的anchor hash fragment并不会使浏览器重新装载网页,所以一个网页的状态得以保持,而网页本身则可以通过一个计时器(timer)来察觉自己anchor hash的变化,从而相应改变自己的状态。
1. http://domain1/TestCross.html:
1: <html>
2: <head>
3: <script>
1:
2: var url = "http://domain2/TestCross.html"
3: var oldHash = null;
4: var timer = null;
5:
6: function getHash()
7: {
8: var hash = window.location.hash;
9: if ((hash.length >= 1) && (hash.charAt(0) == '#'))
10: {
11: hash = hash.substring(1);
12: }
13:
14: return hash;
15: }
16: function sendRequest()
17: {
18: var d = document;
19: var t = d.getElementById('request');
20: var f = d.getElementById('alienFrame');
21: f.src = url + "#" + t.value + "<br/>" + new Date();
22: }
23:
24: function setDivHtml(v)
25: {
26: var d = document;
27: var dv = d.getElementById('response');
28: dv.innerHTML = v;
29: }
30:
31: function idle()
32: {
33: var newHash = getHash();
34:
35: if (newHash != oldHash)
36: {
37: setDivHtml(newHash);
38: oldHash = newHash;
39: }
40:
41: timer = window.setTimeout(idle, 100);
42: }
43: function window.onload()
44: {
45: timer = window.setTimeout(idle, 100);
46: }
</script>
4: </head>
5: <body>
请求:<input> <input value="发送" /><br/>
回复:<div></div>
<iframe src="http://domain2/TestCross.html"></iframe>
</body>
</html>
2. http://domain2/TestCross.html:
1: <html>
2: <head>
3: <script>
1:
2: var url = "http://domain1/TestCross.html"
3: var oldHash = null;
4: var timer = null;
5:
6: function getHash()
7: {
8: var hash = window.location.hash;
9: if ((hash.length >= 1) && (hash.charAt(0) == '#'))
10: {
11: hash = hash.substring(1);
12: }
13:
14: return hash;
15: }
16: function sendRequest()
17: {
18: var d = document;
19: var t = d.getElementById('request');
20: var f = parent;
21: //alert(f.document); //试着去掉这个注释,你会得到“Access is denied”
22: f.location.href = url + "#" + t.value + "<br/>" + new Date();
23: }
24:
25: function setDivHtml(v)
26: {
27: var d = document;
28: var dv = d.getElementById('response');
29: dv.innerHTML = v;
30: }
31:
32: function idle()
33: {
34: var newHash = getHash();
35:
36: if (newHash != oldHash)
37: {
38: setDivHtml(newHash);
39: oldHash = newHash;
40: }
41:
42: timer = window.setTimeout(idle, 100);
43: }
44:
45: function window.onload()
46: {
47: timer = window.setTimeout(idle, 100);
48: }
</script>
4: </head>
5: <body>
请求:<input> <input value="发送" /><br/>
回复:<div></div>
</body>
</html>
两个网页基本相同,第一个网页内嵌一个IFRAME,在点击“发送”按钮后,会将文本框里的内容通过hash fragment传给IFRAME。点击IFRAME里的“发送”按钮后,它会将文本框里的内容通过hash fragment传给父窗口。因为是只改动了hash fragment,浏览器不会重新load网页内容,这里使用了一个计时器来检测URL变化,如果变化了,就更新其中一个div的内容 。
Case IV. 用户本地转储方式 (local)
IE本身依附于windows平台的特性为我们提供了一种基于iframe,利用内存来“绕行”的方案,即两个window之间可以在客户端通过windows剪贴板的方式进行数据传输,只需要在接受数据的一方设置Interval进行轮询,获得结果后清除Interval即可。FF的平台独立性决定了它不支持剪贴板这种方式,而以往版本的FF中存在的插件漏洞又被fixed了,所以FF无法通过内存来完成暗渡陈仓。而由于文件操作FF 也没有提供支持(无法通过Cookie跨域完成数据传递),致使这种技巧性的方式只能在IE中使用。
Case V: (其实还是在服务端A用iframe解决了与服务器B通信的问题)
要解决的问题:发生在用户提交网页 URL (还包括 Tag, Notes 等)给 Bookmark 服务器时。
关于 URL 的提交至少可以有三种方式:
1. 登陆 Bookmark 服务器的提交页面,将要收藏的 URL 通过该页面提交给服务器。
2. 安装浏览器插件,通过插件将 URL 提交给服务器。
3. 从 Bookmark 服务器动态加载 javascript 小工具到当前页面,通过它来完成提交工作。
第一种方式开发起来最简单,但对用户来讲比较麻烦,每次都需要先登陆 Bookmark 服务器才能完成提交;第二种方式我并不熟悉插件开发,而且用户也不喜欢太多的插件堆满自己的浏览器;第三种方式开发难度小,又避免了每次登陆服务器的麻烦,所以最终采用它。第三种方式中动态加载的 javascript 小工具除了需要生成 UI 供用户填写信息( URL , tag , notes 等),当用户点击提交的时候,还要完成与服务器通信的功能。
跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。由于安全原因,跨域访问是被各大浏览器所默认禁止的。写过跨域访问 ajax 的朋友相信都遇到过被告知“没有权限”的情况。通过 XMLHttp 来发送数据给 Bookmark 服务器的尝试失败了。于是,看到网上的一些资料,我又开始尝试用 javascript 小工具在用户网页动态创建一个隐藏的 iframe, iframe 的 src 指向服务器的一个 servlet ,试图通过调用 iframe 中提供的 javascript 来完成与服务器的通信。但不幸的是,用户网页中的 javascript 代码访问 iframe 也被浏览器归为跨域访问(特指 iframe 的 src 指向其它网站的情形),尝试再次失败。
最终,在一篇文章中看到,与 iframe 不同,如果 A 网站从 B 网站加载 javascript , A 网站可以自由的访问该 javascript 的内容,并不会被浏览器认为是跨域访问。模仿刚才 iframe 的思路,当用户点击提交时,可以动态创建一个 javascript 对象,该对象的 src 指向 Bookmark 服务器的一个 servlet ,注意: URL 、 Tag 、 Notes 、 User 、Password 等信息被作为 src URL 参数传给服务器。请看下面的代码:
1: var url = "http://localhost:8080/Deeryard/BookmarkServlet?" +
2:
3: "url=" + url_source + "&" + "title=" + title + "&" +
4:
5: "tag=" + tag + "&" + "notes=" + notes + "&" + "user=" + user + "&" + "password=" + password;
6:
7: url = encodeURI(url);
8:
9: //Submit to server with a trick
10:
11: var js_obj = document.createElement( "script" );
12:
13: js_obj.type = "text/javascript" ;
14:
15: js_obj.setAttribute( "src" , url);
16:
17: //Get response from server by appending it to document
18:
19: document.body.appendChild(js_obj);
20:
上面例子中, js_obj.setArrribute() 将信息作为 src 的 URL 参数提交给了 Bookmark servlet 。那么用户又如何取得服务器的响应信息呢?答案就是最末一行代码, servlet 的输出必须是 javascript 代码,它可以调用用户网页上的其他 javascript 函数,以及操作 dom 对象。下面的 servlet 代码生成了一个 javascript 函数调用:
out.write("onServerResponse(INADEQUATE_INFORMATION);");
document.body.appendChild(js_obj) 执行后 onServerResponse( INADEQUATE_INFORMATION) 就会得到执行,使客户网页响应服务器结果。这样一个完整的通信过程就完成了。
CaseVI:Tomcat + PHP + HTML(含JS)(on Server A)
服务器A上已经装好了Tomcat, 我们写一个test.html(含JS),再写一个PHP文件(由其来完成跨域通信要求)。
转载于:https://www.cnblogs.com/sunBolg/archive/2012/09/13/2683914.html
AJAX跨域访问解决方案相关推荐
- ajax中cors解决跨域,AJAX 跨域 CORS 解决方案
两种跨域方法 在 Javascript 中跨域访问是比较常见的事情 就像现在比较流行写单页应用,而单页应用在访问 API 的时候就会有跨域的问题 要解决跨域的问题,其实也并不复杂,有两种方案可以选择 ...
- 浏览器跨域访问解决方案
浏览器跨域访问解决方案 2015年11月4日 18972次浏览 跨域的概念 跨域大家都知道,不同地址,不同端口,不同级别,不同协议都会构成跨域.例如:about.haorooms.com和www.ha ...
- ajax跨越html,ajax跨域的解决方案
什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容(参考js的同源策略). 但是我们项目开发过程中,经常会遇到在一个页面的JS代码中, ...
- Web应用跨域访问解决方案
Web应用跨域访问解决方案 Web应用的跨域访问解决方案 Web跨域访问解决方案 做过跨越多个网站的Ajax开发的朋友都知道,如果在A网站中,我们希望使用Ajax来获得B网站中的特定内容,如果A网站与 ...
- apache ajax 跨域访问,AJAX跨域访问(从Tomcat8到Apache/Nginx)
1.在Tomcat的Root目录下放入如下的文件 apache-tomcat-8.0.12X64\webapps\ROOT clientaccesspolicy.xml文件 crossdomain.x ...
- ajax跨域情况解决方案,ajax跨域解决方案.docx
ajax跨域解决方案 ajax跨域解决方案 篇一:使用JSONP解决Ajax跨域访问问题 使用JSONP解决Ajax跨域访问问题 JSONP(JSON with Padding)是JSON的一种&qu ...
- ie9以下兼容ajax跨域访问,解决ie9以下浏览器ajax请求报error拒绝访问方案 解决ie9以下浏览器ajax请求报400问题方案
解决方案如下: 1.ie9以下兼容ajax跨域访问 2.ajax请求开始前添加 jQuery.support.cors = true; 允许跨域 3.ie浏览器设置允许通过域访问数据 并且 ur ...
- jsonp跨域的缺点ajax缺点,浅析JSONP解决Ajax跨域访问问题的思路详解
前几天,工作上有一新需求,需要前端web页面异步调用后台的Webservice方法返回信息.实现方法有多种,本例采用jQuery+Ajax,完成后,在本地调试了一切ok,但是部署到服务器上以后就出现问 ...
- Jetty Cross Origin Filter解决jQuery Ajax跨域访问的方法
当使用jQuery Ajax post请求时可能会遇到类似这样的错误提示 XMLHttpRequest cannot load http://xxxxxx. Origin http://xxxxxx ...
最新文章
- Shell---判断(if)和分支(case)
- 关于程序猿的几个阶段!
- 你不知道的《阿里巴巴Java开发手册》背后故事
- Maven STS创建WEB项目
- 北大生物信息学学习(2) 生物学及生物学信息学的发展
- Hive分区入门到精通
- YDUI的移动端页面rem适配方案使用方法记录
- 打印机服务器找不到网络路径,分享0x80070035找不到网络路径的解决方法
- B站的热门视频要怎么同时批量下载保存到本地电脑中
- 师太、老衲、贫道的爱恨全集
- 用文氏图表示映射满射单射及函数的关系
- android ro.boot.mac,Android Verified Boot浅知分享
- 入股不亏!LINQ凭什么被誉为最好的技术?
- Java实现彩色二维码
- java虚拟机内存情况检测,测试啦啦啦啦啦1111
- button按钮的tittle 折行且居中显示
- 中式英语如何产生?该怎么办?
- linux wifi名称设置中文乱码,无线wifi名称怎么改成中文乱码的方法
- nginx sendfile什么作用
- 中国发布域名系统基础软件 “红枫”
热门文章
- 2022-2028年中国光掩膜行业市场行情监测及未来前景规划报告
- 2022-2028年中国塑料编织品的制造行业市场竞争态势及投资方向分析报告
- 浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin
- Redis 笔记(02)— keys 键相关命令(查询数据库key数量、判断key是否存在、指定key过期时间、查看key类型、查看key剩余秒数、选择数据库、删除key、删除数据库)
- 【VS实践】如何在vs中自动添加注释
- Redis 使用技巧
- SpringCloud Alibaba微服务实战(二) - Nacos服务注册与restTemplate消费
- scheduled sampling_seq2seq
- 通俗易懂word2vec详解词嵌入-深度学习
- PyTorch的torch.cat