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跨域访问解决方案相关推荐

  1. ajax中cors解决跨域,AJAX 跨域 CORS 解决方案

    两种跨域方法 在 Javascript 中跨域访问是比较常见的事情 就像现在比较流行写单页应用,而单页应用在访问 API 的时候就会有跨域的问题 要解决跨域的问题,其实也并不复杂,有两种方案可以选择 ...

  2. 浏览器跨域访问解决方案

    浏览器跨域访问解决方案 2015年11月4日 18972次浏览 跨域的概念 跨域大家都知道,不同地址,不同端口,不同级别,不同协议都会构成跨域.例如:about.haorooms.com和www.ha ...

  3. ajax跨越html,ajax跨域的解决方案

    什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容(参考js的同源策略). 但是我们项目开发过程中,经常会遇到在一个页面的JS代码中, ...

  4. Web应用跨域访问解决方案

    Web应用跨域访问解决方案 Web应用的跨域访问解决方案 Web跨域访问解决方案 做过跨越多个网站的Ajax开发的朋友都知道,如果在A网站中,我们希望使用Ajax来获得B网站中的特定内容,如果A网站与 ...

  5. apache ajax 跨域访问,AJAX跨域访问(从Tomcat8到Apache/Nginx)

    1.在Tomcat的Root目录下放入如下的文件 apache-tomcat-8.0.12X64\webapps\ROOT clientaccesspolicy.xml文件 crossdomain.x ...

  6. ajax跨域情况解决方案,ajax跨域解决方案.docx

    ajax跨域解决方案 ajax跨域解决方案 篇一:使用JSONP解决Ajax跨域访问问题 使用JSONP解决Ajax跨域访问问题 JSONP(JSON with Padding)是JSON的一种&qu ...

  7. ie9以下兼容ajax跨域访问,解决ie9以下浏览器ajax请求报error拒绝访问方案 解决ie9以下浏览器ajax请求报400问题方案

    解决方案如下: 1.ie9以下兼容ajax跨域访问   2.ajax请求开始前添加 jQuery.support.cors = true;  允许跨域 3.ie浏览器设置允许通过域访问数据 并且 ur ...

  8. jsonp跨域的缺点ajax缺点,浅析JSONP解决Ajax跨域访问问题的思路详解

    前几天,工作上有一新需求,需要前端web页面异步调用后台的Webservice方法返回信息.实现方法有多种,本例采用jQuery+Ajax,完成后,在本地调试了一切ok,但是部署到服务器上以后就出现问 ...

  9. Jetty Cross Origin Filter解决jQuery Ajax跨域访问的方法

    当使用jQuery Ajax post请求时可能会遇到类似这样的错误提示 XMLHttpRequest cannot load http://xxxxxx. Origin http://xxxxxx ...

最新文章

  1. Shell---判断(if)和分支(case)
  2. 关于程序猿的几个阶段!
  3. 你不知道的《阿里巴巴Java开发手册》背后故事
  4. Maven STS创建WEB项目
  5. 北大生物信息学学习(2) 生物学及生物学信息学的发展
  6. Hive分区入门到精通
  7. YDUI的移动端页面rem适配方案使用方法记录
  8. 打印机服务器找不到网络路径,分享0x80070035找不到网络路径的解决方法
  9. B站的热门视频要怎么同时批量下载保存到本地电脑中
  10. 师太、老衲、贫道的爱恨全集
  11. 用文氏图表示映射满射单射及函数的关系
  12. android ro.boot.mac,Android Verified Boot浅知分享
  13. 入股不亏!LINQ凭什么被誉为最好的技术?
  14. Java实现彩色二维码
  15. java虚拟机内存情况检测,测试啦啦啦啦啦1111
  16. button按钮的tittle 折行且居中显示
  17. 中式英语如何产生?该怎么办?
  18. linux wifi名称设置中文乱码,无线wifi名称怎么改成中文乱码的方法
  19. nginx sendfile什么作用
  20. 中国发布域名系统基础软件 “红枫”

热门文章

  1. 2022-2028年中国光掩膜行业市场行情监测及未来前景规划报告
  2. 2022-2028年中国塑料编织品的制造行业市场竞争态势及投资方向分析报告
  3. 浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin
  4. Redis 笔记(02)— keys 键相关命令(查询数据库key数量、判断key是否存在、指定key过期时间、查看key类型、查看key剩余秒数、选择数据库、删除key、删除数据库)
  5. 【VS实践】如何在vs中自动添加注释
  6. Redis 使用技巧
  7. SpringCloud Alibaba微服务实战(二) - Nacos服务注册与restTemplate消费
  8. scheduled sampling_seq2seq
  9. 通俗易懂word2vec详解词嵌入-深度学习
  10. PyTorch的torch.cat