Ajax 跨域请求 jsonp获取json数据

遇到Ajax的跨域请求出问题 找了中解决的方法例如以下:

參考内容:http://justcoding.iteye.com/blog/1366102


因为受到浏览器的限制。该方法不同意跨域通信。

假设尝试从不同的域请求数据。会出现安全错误。假设能控制数 据驻留的远程server而且每一个请求都前往同一域。就能够避免这些安全错误。可是,假设仅停留在自己的server上,Web 应用程序还有什么用处呢?假设须要从多个第三方server收集数据时,又该怎么办?

 

理解同源策略

同源策略阻止从一个域上载入的脚本获取或操作还有一个域上的文档属性。也就是说。受到请求的 URL 的域必须与当前 Web 页面的域同样。

这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略非常旧,从 Netscape Navigator 2.0 版本号開始就存在。

 

克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web server请求数据,而且让 Web server像代理一样将请求转发给真正的第三方server。虽然该技术获得了普遍使用。但它是不可伸缩的。还有一种方式是使用框架要素在当前 Web 页面中创建新区域,而且使用 GET 请求获取不论什么第三方资源。只是,获取资源后,框架中的内容会受到同源策略的限制。

 

克服该限制更理想方法是在 Web 页面中插入动态脚本元素,该页面源指向其它域中的服务 URL 而且在自身脚本中获取数据。脚本载入时它開始运行。该方法是可行的,由于同源策略不阻止动态脚本插入。而且将脚本看作是从提供 Web 页面的域上载入的。

但假设该脚本尝试从还有一个域上载入文档,就不会成功。

幸运的是。通过加入 JavaScript Object Notation (JSON) 能够改进该技术。

 

1、什么是JSONP?

 

要了解JSONP。不得不提一下JSON。那么什么是JSON ?

JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.

JSONP(JSON with Padding)是一个非官方的协议,它同意在server端集成Script tags返回至client。通过javascript callback的形式实现跨域訪问(这不过JSONP简单的实现形式)。

 

2、JSONP有什么用?

因为同源策略的限制。XmlHttpRequest仅仅同意请求当前源(域名、协议、port)的资源,为了实现跨域请求,能够通过script标签实现跨域请求。然后在服务端输出JSON数据并运行回调函数。从而攻克了跨域的数据请求。


3、JSONP原理
首先在client注冊一个callback, 然后把callback的名字传给server。

此时,server先生成 json 数据。


然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的參数 jsonp.

最后将 json 数据直接以入參的方式,放置到 function 中,这样就生成了一段 js 语法的文档。返回给client。

client浏览器,解析script标签,并运行返回的 javascript 文档。此时数据作为參数,传入到了client预先定义好的 callback 函数里.(动态运行回调函数)

4、JSONP优缺点

JSONP 是构建 mashup 的强大技术,但不幸的是,它并非全部跨域通信需求的万灵药。它有一些缺陷,在提交开发资源之前必须认真考虑它们。

 

第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。假设动态脚本插入有效。就运行调用;假设无效,就静默失败。失败是没有不论什么提示的。

比如。不能从server捕捉到 404 错误。也不能取消或又一次開始请求。只是。等待一段时间还没有响应的话。就不用理它了。

(未来的 jQuery 版本号可能有终止 JSONP 请求的特性)。

 

JSONP 的还有一个主要缺陷是被不信任的服务使用时会非常危急。由于 JSONP 服务返回打包在函数调用中的 JSON 响应。而函数调用是由浏览器运行的,这使宿主 Web 应用程序更easy受到各类攻击。假设打算使用 JSONP 服务,了解它能造成的威胁非常重要。



详细实现:

前台Ajax请求  在ajax的函数中新增一行 dataType:'jsonp', 标示为跨域的请求例如以下:

</pre><pre name="code" class="java"><script>
	function sendJson(){
		var value = $("#xiaoh").val();
		alert(value);
		 $.ajax({
	   			type : 'post',
	   			dataType:'jsonp',
	   			url  : 'http://localhost:8080/springMVC/jsonDo',  
	   		    data : {'tokenId' : value},
	   			success : function(data){
	   	   			alert(data.tokenId);
	   		    },
	   		    error : function(data) {
	   		    	alert(data.tokenId);
	   		    }
	   	    }); 
	       
	}
</script>

action的后台代码也要做对应的处理,例如以下

在jsonDo的參数值中增加  String callback參数,这个參数在前台的ajax中不用赋值,jquery会自己主动给这个參数赋值的,

然后再后台中封装下返回这个參数值     callback({。

。})   ,  大括号里传要返回的參数即可。以下是样例:

 @RequestMapping(value="/jsonDo" , produces = "application/json;charset=UTF-8")    
	    public @ResponseBody String jsonDo(String tokenId, String callback) {  
		 System.out.println("tokenId:"+tokenId);
		 StringBuilder sb = new StringBuilder();
			sb.append(callback);
			sb.append("(");
			sb.append("{\"tokenId\":\"111111111\"}");
			sb.append(")");
	        return sb.toString();          
	    }  


posted @ 2016-02-21 09:37  blfshiye  阅读(222)  评论(0编辑  收藏  举报