浅谈客户端跨域

主要参考文章:http://www.cnblogs.com/wangfupeng1988/p/4060747.html

项目是分布式的,跨域是个绕不过去的坎,分2种方式:

1、服务器端跨域httpclient很多例子了。这里就不谈了。

2、客户端跨域(主要解释)

客户端的跨域,在服务器代码没有声明的前提下直接访问是会报错的。No 'Access-Control-Allow-Origin

但是浏览器会引入其他域的js文件,所以一个想法诞生了:

一 、 其他域的js文件代码http://localhost/source.js

xhrHandler({"id":"123"});

调用页面代码localhost:8080/test.html

xhrHandler(data){
    alert(data.id);
}
<script language="javascript" src="http://localhost/source.js">

从域名可以看出来端口号变化了,可以依然能引入source.js,那么上面的代码相当于:

function xhrHandler(data){
    alert(data.id);
}
xhrHandler({"id":"123"});

是的,相当于声明了xhrHandler方法,又执行了这个方法。

二、下来思路就成了,如何将想请求的Controller生成一个js,就可以绕过浏览器了。

下来的Controller代码:

@RequestMapping(value="/test",method=RequestMethod.GET)
    @ResponseBody
    public String test(HttpServletRequest request, HttpServletResponse response){
        String callback = request.getParameter("callback");
        if(callback != null){
            return callback + "({'id':'123'})";
        }else{
            return "error";
        }
    }

调用的js代码:

    function test(){        
        addScriptTag("http://localhost:81/search/epinfo/test?callback=xhrHandle");
    }
    
    function xhrHandle(data){
        alert(data.id);
    }
    
    function addScriptTag(src) {
        var script = document.createElement("script");
        script.setAttribute("type", "text/javascript");
        script.src = src;
        document.body.appendChild(script);
    }

当test()方法执行,调用addScriptTag()方法,发送地址,请求了一个跨域页面,

然后构造了一个<script type=text/javascript src=****></script>的js引用。

在服务器端返回了一个xhrHandle(json)的字符串。上面的代码相当于

  function xhrHandle(data){
        alert(data.id);
    }
    
   xhrHandle(服务器端需要传值的json对象);

所有操作只为了一个目的-----传值,分成2步

1、在服务器端返回字符串xhrHandle(data);

2、在客户端构造<script language="javascript" >xhrHandle(data);</script>

这就是JSONP,和ajax,和json没关系!没关系!没关系!重要的事情说三遍!

三、下来试试jquery方式

jquery方式调用,更简单,也更类似ajax方式,他只是将上面的方法进行包装

默认的有一个callback参数,你申请的页面就成了http://ip:port/***?callback=随机生成的一个乱七八糟的方法名

用谷歌控制台可以明显看出来申请地址的变化,实例如下:

  function test(){
        $.ajax({
            url: "http://localhost:81/search/epinfo/test",//?callback=xhrHandle",
            type: 'GET',
            dataType: 'JSONP',//here
                    
            success: function(data) {
                alert(data.id);
            }
        });        
    }

是不是很像ajax?可惜和ajax没关系,-_-!!

更进一步,如果想自定义回调函数名,应该这样:

客户端

  function test(){
        $.ajax({
            url: "http://localhost:81/search/epinfo/test",//?callback=xhrHandle",
            type: 'GET',
            dataType: 'JSONP',//here
            jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
            jsonpCallback:"success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名            
            
        });        
    }

  function success_jsonpCallback(data){
        alert(data.id);
    }

服务器端:

@RequestMapping(value="/test",method=RequestMethod.GET)
    @ResponseBody
    public String test(HttpServletRequest request, HttpServletResponse response){
        String callback = request.getParameter("callback");
        if(callback != null){
            return callback + "({'id':'123'})";
        }else{
            return "error";
        }
    }

jquery只是封装了一下,自动生成了一个回调函数,并且在success后执行。

收工~!

原文地址:https://www.cnblogs.com/PPBoy/p/7263263.html