使用jquery的getjson()遇到的跨域访问问题




环境描述

  • 服务器:使用jersey提供RESTful接口
  • 客户端:使用jquery的getJson()方法异步获取数据
  • 希望实现的功能:服务器端以json格式提供RESTful的数据访问,客户端通过ajax异步加载的方式读取数据。

出问题代码

(其实下面代码也不包含错误,只是在执行的时候会出问题)

客户端原始代码:

document.getElementById("mydiv").innerHTML = "data";
$(function(){
     $.getJSON("******", function (data) {
         alert("go");
         document.getElementById("mydiv").innerHTML = "hahahah";
     });
});
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

服务器端原始代码:

@GET
@Path("/test")
@Produces("application/json;charset=utf8")
public String go(){
    return "({\"num\":\"3\"}";
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

结果运行的时候就出问题了,客户端的回调函数死活不执行。用Firefox的Httpfox调试下,发现在获取json数据的时候就遇到问题,报错application/json (NS_ERROR_DOM_BAD_URI)
网上找了下,说是jquery跨域访问的安全问题,就是说:

JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。

上边的代码中,客户端和服务端确实在不同的服务器,使用不同的IP地址和端口号,因此出现了问题。

解决办法就是JSONP,全称是 JSON with Padding ,是基于 JSON 格式的为解决跨域请求资源而产生的解决方案。其基本原理是利用了 HTML 里 元素标签可以跨域访问,因此将数据封装成为js回调函数的格式进行传输访问。

举个例子,上述的数据{"num":"3"},这时不能跨域访问的,那么救把它包装为js,callback('{"num":"3"}'),将数据包装为回调函数的参数,就可以跨域访问了。这就需要解决一个问题,提供数据访问的服务器必须进行数据封装的操作,如果响应的时候还是把原来的json格式数据输出,那么客户端是拿不到需要的数据的。

如果说服务器没有对数据进行封装,那么出现的问题就是回调函数死活不执行。即使用Httpfox进行调试,也会发现虽然正确访问了数据链接,服务器也返回了数据,但回调函数就是执行不了。就是因为这个问题困了我整整两天……

解决方案

其实jQuery已经封装了JSONP的使用

$.getJSON( "****?jsoncallback=?", function( data ){
    // 处理跨域请求得到的数据
});
  
  
  • 1
  • 2
  • 3

jquery会把jsoncallback后边的?替换为一个字符串作为数据访问的回调函数的函数名,在服务器端需要读取该参数,然后使用它对数据进行封装,也就是改成f(data)的样式,加上函数名和括号就行了。

服务器端代码为:

    @GET
    @Path("/test")
    @Produces("application/json;charset=utf8")
    public String go(@QueryParam("jsoncallback") String jsoncallback){
        System.out.println(jsoncallback);
        String info = jsoncallback+"({\"num\":\"3\"})";
        return info;
    }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ok,再访问就没有问题了!


PS:最后吐槽一下网络上的各种解决方案,都是只给一个jsoncallback参数,服务器需要怎么改一点都不说,结果整整两天一直困在回调函数不执行的苦恼中……

感谢基于JQuery、Jsonp与Jersey的跨域访问这篇文章替我找到了回家的路!







环境描述

猜你喜欢

转载自blog.csdn.net/qq_38643434/article/details/81589759