跨域问题小记以及jsonp简谈

前端之家收集整理的这篇文章主要介绍了跨域问题小记以及jsonp简谈前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

去年,在给导师做项目时需要解决一个跨域问题,当时没弄过,就从网上找了资料给解决了,时至今日让我再提怎么做的,早已忘掉。再有就是以前听过jsonp,但是对此概念全然不知,只觉得跟json只差一个p。直到前几天带我的师傅跟我说了下jsonp,然后又自己查看了jsonp的原理后,才知道jsonp是怎么一回事。为了以后自己可以快速拾起这些知识,在这里粗略记录一下。


iframe跨域

1.遇到的问题

我们的页面A.html

别人的页面B.html(两个页面不同域)

A.html要嵌套B.html页面,而且被嵌套的B.html页面需要调用A.html的js方法

思想:

在a.html同一个域下创建一个c.html,就是利用c.html这个页面来作为b.html页面访问a.html页面js方法的桥梁

通过在a.html中嵌套b.html,然后在嵌套在a中的b.html页面中再(有点绕,仔细体会)动态创建一个iframe,把c.html页面嵌套进去,然后b.html便可以通过动态嵌套的c.html页面调用a.html的js方法了。

随便画了张图,表示下嵌套的层次:


实现:

直接上代码比较清楚:(ip跟域名来说不是在同一个域下,所以可以用一台机子中ip127.0.0.1与localhost来模拟)

localhost:8080/test1/a.HTML代码

<html>
<head>
<title>无标题文档</title>
</head>

<body>
<iframe src="http://127.0.0.1:8080/test2/b.html"  frameborder="0" scrolling="no" marginheight="0" marginwidth="0" name="myframe"></iframe>
<script>
	function test(data)
	{
	  alert("这个是a中的方法,参数:"+data);
	}
</script>
</body>
</html>
这段代码中嵌套了b.html页面,然后,我们的目的是点击b.html页面中按钮可以调用a.html页面中的test方法

localhost:8080/test1/c.HTML代码 (c.html页面与a.html页面在同一个域中,实验中与a.html页面同一目录下了)

<html>
<head>
<Meta charset="utf-8">
<title></title>
<script>
window.onload = function(){
    var text = window.location.href.split('=')[1]
    parent.parent.test(text);
}
</script>
</head>
<body>

</body>
</html>
c.html页面中没有什么代码,就是为了b.html页面调用页面的时候,帮助调用a.html中的方法

c调用a的方法的时候用了 parent.parent.方法名来调用的,因为c是作为a底下两层嵌套。


127.0.0.1:8080/test2/b.HTML代码

<!doctype html>
<html>
<head>
<Meta charset="utf-8">
<title>跨域测试</title>
</head>

<body>
<ul>
<li>测试</li>
</ul>
<input type="button" onclick="exec_iframe()" value="调用a页面方法"></input>
<script>
	 function exec_iframe(){  //此方法就是动态创建iframe,然后将c.html页面嵌套进来
	  var text = "abcddddddd";
      if(typeof(exec_obj)=='undefined'){  
        exec_obj = document.createElement('iframe');  
        exec_obj.name = 'tmp_frame';  
        exec_obj.src = 'http://localhost:8080/test1/c.html?content='+text;  
        exec_obj.style.display = 'none';  
        document.body.appendChild(exec_obj);  
    }else{  
        exec_obj.src = 'http://localhost:8080/test1/c.html?content='+text;  
    }  
  } 
</script>
</body>
</html>
当点击b中的按钮时,会调用方法exec_iframe(),然后动态将c页面嵌套进来,c页面初始化便会调用页面中的js方法,便实现了调用a页面中的test方法


----------------------------------------------------------------------------------------------------------------
总结下流程:

启动tomcat,访问a.html页面


b页面中的内容便加载进来了,在b.html中有文本以及一个按钮,然后点击按钮,去调用a.html中的方法,这个过程就是上面说的,在b中动态嵌入c页面,然后由c页面调用a中的方法。(参数没有转码,没什么影响)



同理,如果想在a中调用b中的方法的话,那可以在b.html同目录下或者说同域下创建一个页面d,d中调用b中的方法(parent.window.myframe.方法名,此处的myframe是b在a页面中的iframe名称),当a也调用b中方法的时候,同样在页面中动态创建一个iframe来嵌套d页面


jsonp简谈

以我自己的理解,jsonp不是什么协议,更不是什么数据格式,只是帮助获取外域数据的一种方法

这种方法就是利用了浏览器对<script src ="http://.............." ></script>不采取“同源策略”的特点来实现数据获取的。

当我们使用src时,是可以调用别的站点的资源,举例来说:

a.html页面中有段js

<script>
 function test()
{ 
    alert("通过远程资源文件调用我啊");
}
</script>
<script src="http://xxxxx/remote.js"></script>

远程的这个remote.js文件内容是:

test();

那当a页面加载时会弹出弹框。

其实,这就是jsonp的依赖的原理,src指向的不止是一个js文件,同样可以是一个请求地址:

src="http://xxxx/xxxx/getcount?callback=test"(callback就是一个普通参数名,完全可以换成别的,只要跟后台约定好就ok了)

这样的话我们可以在后台方法getcount中拿到参数callback,这个callback参数是干嘛的呢,就是向后台说明你从后台拿到数据后,要用哪个方法来处理,也就是让后台给你返回像上面test()方法这样的东西。

给个完整例子就是:

<script>
 function dealcount(data)
{ 
    alert("获取后台数据:"+data);
 //拿到数据,处理数据
}
</script>
<script src="http://xxxx/xxxx/getcount?callback=dealcount"></script></span>

当这个页面加载的时候便回去请求这个链接后台拿到参数test,以及经过后台处理好的数据data,然后返回来 dealcount(data),那么这个是不是就跟remote.js中写个dealcount(data)一样了,就会执行自己页面上写的dealcount(data)方法了。


但是这个例子是个静态的,不能每次都是页面加载的时候来请求吧。要需要时再去请求,那就写个方法去动态生成script标签,然后动态加载到页面中吧。

function jsonpRequest(){ 
   var url = "http://xxxx/xxxx/getcount?callback=dealcount";</span>
    //创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src',url);
    //把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script);
}

jsonp在jquery中也可以使用ajax的方式,只要知道了这个jsonp是个什么东西,那么ajax中的使用也就是一看便明了 了。


如果有别的跨域以及这方面的知识,可以推荐给我,谢谢!





--------------------等回头看看自己,写的又傻又笨的时候,那么说明我成长了!

猜你在找的Json相关文章