深入理解jsonp解决跨域访问

       在我们做的这个项目中充分利用jsonp跨域这一个特性,完成了简单的单点登录功能和权限统一认证控制,实现思路并不复杂同各种实现单点登录的产品相比可以说微不足道,各有各的好处、各有各的优点,选择什么方式实现完全取决于我们自己或者项目经理的开发经验,对各种框架的理解程度往往决定了目前开发项目的整体架构。

      这不是一项凭空产生的新东西,仅仅是JS的一个特性而已之前没有被我们提及也没有被我们注意到原来经常使用的js还可以跨域呢,觉的我们对已经学过的东西理解还不是不够深入、有些肤浅,JS绝大多数在浏览器中运行完成各种动态效果,开发js的人一开始应该就考虑到了浏览器的特性,为了不受浏览器的限制而将js赋予了这一个神圣的职责,浏览器的限制是安全策略里面的一个策略,叫同源策略。

同源策略

      同源的意思是协议、域名、端口都相同,只要有一个不相同那么就是不同源的访问地址,一个浏览器的一个页面中是不可以从不同源的地址获取数据的,当每次页面加载时浏览器都会自动判断获取的数据是否来自一个源地址,如果不是会受到浏览器的阻止。

好像会议的安检一样,只允许某一类有通行证的人进入,其他的则不会让进入阻止在外面,而js有一个特性可以跨过安检通过特殊途径进入不受阻止。

解决同源策略问题jsonp
      Jsonp(JSON with Padding)是资料格式 json 的一种“使用模式”,可以让网页从别的网域获取资料。

之所以叫jsonp可以理解为主要作用和目的就是从别的网域获取json格式数据,这是它的主要应用方面,其它的作用暂时没有用到。

原理

      原理也很容易理解,它之所以可以跨域是利用了script标签的跨域能力,试想?你有没有想过经常引入的一个普通js文件,它是怎么样加载到页面中去的为什么它的src属性写上一个地址就可以把别处的js文件加载到页面上呢,经测试这个src属性可以填写任意有效的地址,即使不在同一个项目目录结构中的文件也是可以的。

      例如这个链接;

<span style="font-size:14px;"><script type="text/javascript" src="_js/jquery-2.0.0.min.js"></script></span>

      它只是一个引用,加载进来的文件时很多这样的函数function(){}………………,同理jsonp就是这样一种模式,它返回的也是js函数同上面这个链接没有什么区别,只是函数名叫做回调函数需提前定义好,函数里面是返回的json数据。我们来看一个实例:

<span style="font-size:14px;">	<script type="text/javascript">
		
		function getjson(json)
		{
			alert("通过src属性获得json="+json.result);
		}
	</script>
	
	<script type="text/javascript" src="http://localhost:28080/application1/login.do?method=loginInterface&callback=getjson&name=lilongsheng"></script></span>

      这是我自己写的一个js标签,它的src地址是另一个tomcat中部署的application1应用的登录接口地址,而上面调用是在另一个tomcat中的application2 jsp页面,属于不同源调用,再来看一下application1中接口类

<span style="font-size:14px;">    public ActionForward loginInterface(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
    {

    	/** 判断是否登录成功 */
		boolean isLogin = false;
		//从用URL中获取用户名和密码
    	String name=request.getParameter("name");
    	String pwd=request.getParameter("pwd");
		try {
			//回调函数名
			String callbackFunName = request.getParameter("callback");
			//利用jsonp包装的json数据
			String data = callbackFunName + "({"result":"" + name + ""})";
	
			System.out.println(data);
			//返回到界面
			print(data,request,response);
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
    }</span>

      返回结果为gejson({"result":"lilongsheng"}),返回的是一个JS代码,它会自动执行getjson这个函数,而花括号{}里面的内容正好当做参数传递到这个函数里面,完成跨域调用。

      从上面可以看出通过script标签可以从不同源的地方获得json数据。

我们再来看看jquery是如何使用的,仅仅在方法中加入一个参数就可以实现,感觉简单了很多,这是因为框架已经为我们封装好了里面的一些细节调用关系,只要我们设置了参数它就支持跨域访问,调用如下:

<span style="font-size:14px;">		function getJsonp()
		{
			var name=$("#name").val();
			var pwd=$("#pwd").val();
			$.ajax({
				url:"http://localhost:28080/application1/login.do?method=loginInterface&name="+name+"&pwd="+pwd,
				type:"post",
				dataType:"jsonp",
				jsonp : 'callback',
				success:function(data){
					alert(data.result);
				},
				error:function(){
					alert("网络连接失败!");
				}
			});
		}</span>

      除了jquery之外还有ext等框架都支持这一特性,它们都是基于javaScript基础类库封装起来的,因此都具有js具有的特性。

      关于jsonp的如何应用已经录了一集视频,下面是下载地址

      jsonp视频演示下载地址:http://pan.baidu.com/s/1dDIjnTR







原文地址:https://www.cnblogs.com/lilongsheng1125/p/4978515.html