脱离jsonp,如何跨域读取、提交数据 da宗熊

本文介绍了JSONP的基本原理及其局限性,并提出了一种利用iframe和document.domain实现的跨域数据提交方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、JSONP


刚接触javascript,跨域首先想到的就是JSOP,接而,用到的,就是jQuery的getJSON方法。


JSONP的原理很简单:

         a、浏览器的安全策略,导致了javascript不能垮域名读取数据,就算是父子域也不行。

               但是,跨域读取脚本,是个例外。

         b、动态生成一个scrip标签,把src设为后端借口地址,后端将数据,封装返回成javascript函数。

前端即可在脚本加载完后,执行后端的脚本。


可能说得有点抽象,看个例子吧:

后端代码:

  1. public String getAction(){  
  2.       
  3.     int i = 10;  
  4.     return "jsonp1({value:"+ i +"})";  
  5.   
  6. }  

假如,http://xxx.csdn.com/get.action访问的是上述代码

那前端,只要这么做,就能拿到后端 “i” 的值。

前端代码:

  1. <!-- 预先定义jsonp1函数 -->  
  2. <script>  
  3.     function jsonp1(data){  
  4.        alert(data.value);  
  5.    }  
  6. </script>  
  7. <!-- 等下面脚本加载完成,即会执行jsonp1函数 -->  
  8. <script src="http://xxx.csdn.com/get.action"></script>  

应该不难理解,为什么前端能执行 jsonp1 函数吧?

因为浏览器吧 http://xxx.csdn.com/get.action 返回的字符串,当作了可执行的脚本 --------> jsonp1({value: 1}) ;

SO~



2、脱离JSONP

jsonp读取数据时,非常好用,而且,经过了jQuery的封装,

只要遮样子: $.getJSON("你的连接" + “?callback=?”, params, callback)

jQuery就会默认使用<script>方式,加载数据(当然,前提是你的后端哥们,有对callback参数进行处理啦~~


但是,JSONP不是万能的。

         a、script加载,实际是get请求,对于保密要求高的数据,不适用

         b、虽然说,get请求木有限制提交字符的长度,但是,浏览器的输入栏,是有长度限制的。SO,太大的数据,无法提交

综合来说,JSONP适用于查询数据,或者提交不怎么重要的数据。


那大数据的提交,该何去何从呢?下面,针对兄弟域间数据提交,进行讨论


首先,学习兄弟域数据交互前,要了解几个知识点:

 A、document.domain


  只要将不同域名的两个网页的document.domain设为他们的父域名,两个页面将能通讯
  如:
  a.csdn.com/a.html 里,同一个函数 function funcA,有一个iframe,iframe的地址是 b.csdn.com/b.html
  b.html要访问a.html,b.html里,无论通过top或parent,来访问funcA,浏览器都会提醒:不能跨域读取数据
  但是,只要在a.html 和 b.html里,分别设置了document.domain=csdn.com,在来运行一下,你会发现,浏览器再也不会提醒不能跨域读取啦~
  PS:注意在调用跨域读取函数前,两个页面都已经设置了document.domain了哦~~(血的经验教训啊)。


B、iframe.contentWindow


  b.html读取a.html的内容,只要通过top或parent即可,如在b.html里,调用a.html的函数,可如下调用: parent.funcA();
  但是反过来,a.html要调用b.html的内容呢?
  这时候,就需要contentWindow了。
  大家可以姑且任务,contentWindow 就约等于 window,而实际上,它们两个的属性也是一模一样的。
  不过,contentWindow是递属于iframe的属性,我们可以通过iframe.contentWindow来读取iframe引用的页面的window对象。

 
来重点就来了,了解了上面的知识,大家应该也有个思路了吧?
 
FIRST:给顶级网页,添加document.domain
SECOND:建立一个提交数据用的iframe,也设置相同的document.domain

                (我一般会给iframe的代理页面,引入jQuery)
THIRD:找到iframe的contentWindow,调用相关的方法,如iframe.contentWindow.$.post,给后端发送数据。



很简单吧?其实跨域提交数据,真心不难,捉住两个点,随便玩~。


 

随手找了个两年前的代码,希望帮到各位鞋童:


[javascript] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * create by: da宗熊 
  3.  * create time: 2012-12-25 
  4.  * e-mail:    384858402@qq.com  
  5.  * example:  var cross = MakeCross({自己的配置});  cross.post(url, param, callback); 
  6. **/  
  7. if(!window.MakeCross){  
  8.     function MakeCross(p){  
  9.         var CrossMethod = {  
  10.            CrossUrl:"http://my.test.com/common/cross-domain.jsp",  // 代理页面的地址,我会在代理页面加入jQuery和document.domain  
  11.            Frame:"<iframe id='$0' src='$1' style='visibility:hidden;height:0;width:0;overflow:hidden;border:none;'></iframe>",  
  12.            FrameId :"myCrossFrame_" + MakeLog.frameId++,  
  13.            Domain :"test.com",  
  14.            InitSymbol : "hasInit"  // 标志 iframe 是否加载完毕  
  15.         },  
  16.         that = $.extend(CrossMethod, p);  // 覆盖默认值  
  17.         document.domain = that.Domain;   
  18.           
  19.         // 加载跨域用的 iframe   
  20.         function init(){  
  21.               if(!$("#"+that.FrameId).length>0){  
  22.                   $("body").append(that.Frame.replace("$0",that.FrameId).replace("$1",that.CrossUrl));  
  23.               }  
  24.         }  
  25.           
  26.         // 获取 iframe 的contentWindow  
  27.         function GetCrossWindow(){  
  28.            var win = $("#"+that.FrameId)[0].contentWindow||document.getElementById(that.FrameId).contentWindow;  
  29.            return win;  
  30.         }  
  31.         that.CrossWindow = GetCrossWindow;  
  32.         that.init = function(cb){  
  33.               init();  
  34.               if($("#"+that.FrameId).length>0){  
  35.                   var f = $("#"+that.FrameId);  
  36.                   f.load(function(){  
  37.                      cb?cb():function(){};  
  38.                      $("#"+that.FrameId).attr(that.InitSymbol, "true");  
  39.                      that.init = null;  
  40.                   });  
  41.               }  
  42.         }  
  43.         // 封装jQuery的post和get方法  
  44.         that.post = function(a,b,c,d){  
  45.           return !$("#"+that.FrameId).attr(that.InitSymbol) ? that.init(function(){GetCrossWindow().$.post(a,b,c,d)}) : GetCrossWindow().$.post(a,b,c,d);  
  46.         }  
  47.         that.get = function(a,b,c,d){  
  48.           return !$("#"+that.FrameId).attr(that.InitSymbol) ? that.init(function(){GetCrossWindow().$.get(a,b,c,d)}) : GetCrossWindow().$.get(a,b,c,d);  
  49.         }  
  50.         that.win = GetCrossWindow;  
  51.         return that;  
  52.     };  
  53.     MakeCross.frameId = 1;  
  54. };  
  55. // 多年前写的,优化什么的,就懒得管了 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值