jquery Ajax跨域请求

这是jquery api文档对跨域请求的解析:如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用JSONP类型。使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面。服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求。如果要指定回调函数的参数名来取代默认的callback,可以通过设置$.ajax()的jsonp参数。

我们通过demo来参悟上面的解析:

                $.ajax({
                    type: "get",
                    url: "http://www.yourdomain.com/site/test",//实际上访问时产生的地址为: http://www.yourdomain.com/site/test?callback=jsonpCallback&id=1
                    data: { id: 1 },
                    dataType: "jsonp",
                    success: function (data) {
                        alert(data.statu);
                    },
                    error: function (XMLHttpRequest,textStatus,errorThrown) {
                        alert(XMLHttpRequest.status);
                        alert(XMLHttpRequest.readyState);
                        alert(textStatus);
                    }
                });

上面就是一个最简单的跨域访问请求了。好了,来说说跟普通ajax的区别。首先实际上访问时的地址为:

 http://www.yourdomain.com/site/test?callback=随机数&id=10。参照api定义:
使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面。

这个随机数是jQuery自动生成的。采用jsonp类型情况下,最终生成的url就是如此的。

接下来,看看后台:

服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求。

这是服务器(C# MVC)的代码:

        [HttpGet]
        public string test(string callback, string id)
        {
            return callback + "(" + "{\"statu\":" + id + "});";
        }

一个有效的JSONP请求,需要在JSON数据前加上回调函数名。回调函数名是上面url中callback传递过来的值。此时服务器传递过来的值为:

jQuery18308788135794457048_1419557549884({"statu":"1"});

alert(data.statu);也能正确的输出“1”。有人会说json数据前还有回调函数名么,不用处理也能正常输出data.statu??是的,这就是JSONP。

至此,API的前3句已经解析清楚了。就剩后半句了。上面的callback是jQuery随机生成的,回调函数名也是固定为callback,倘若用户要自己定义呢?这就需要用到最后一句话了。

如果要指定回调函数的参数名来取代默认的callback,可以通过设置$.ajax()的jsonp参数。

ajax代码如下:

                $.ajax({
                    type: "get",
                    url: "http://www.yourdomain.com/site/test",//实际上访问时产生的地址为: http://www.yourdomain.com/site/test?mycallback=jsonpCallback&id=1
                    data: { id: 1 },
                    dataType: "jsonp",
                    jsonp: "mycallback",
                    jsonCallback: "jsonpCallback",
                    success: function (data) {
                        alert(data.statu);
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus);
} });

看到代码应该懂了吧。jsonp属性是设置传递过去的请求参数名的。jsonCallback属性则是自定义传递过去的参数。此时实际访问的url为:

http://www.yourdomain.com/site/test?mycallback=jsonpCallback&id=1

接下来就不细说了。后台接收代码:
        [HttpGet]
        public string test(string mycallback, string id)
        {
            return mycallback + "(" + "{\"statu\":" + id + "});";
        }

接收过来的数据:

jsonpCallback({"statu":"1"});

强调一下的就是。JSONP类型 ajax只支持get请求,post请求的情况已经测试过,是不行的。

至此,api的解析全部解析透了。

接下来,就是曲折版了。

        function test() {
            alert("I am back~~");
        }
          $.ajax({
                    type: "get",
                    //async: false,
                    url: "http://www.yourdomain.com/site/test", //实际上访问时产生的地址为: test?callback=jsonpCallback&id=10
                    data: { id: 10 },
                    cache: false, //默认值true
                    dataType: "jsonp",
                    jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
                    jsonpCallback:"test",
                    //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
                    //如果这里自定了jsonp的回调函数,则回调函数先起作用,后是success函数
                    success: function (data) {
                        alert(data.statu);
                        //alert(json.message);
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        alert(XMLHttpRequest.status);
                        alert(XMLHttpRequest.readyState);
                        alert(textStatus);
                    }
                });

假如你传递过去的jsonpCallback参数为一js函数的话,也是可以的。成功回调之后,会首先调用jsonpCallback函数,然后是success函数。也就是会先alert("I am back~"),后alert(10)。

注意:jsonpCallback属性不能为匿名函数。即不能如下:

          $.ajax({
                    type: "get",
                    //async: false,
                    url: "http://www.yourdomain.com/site/test4", //实际上访问时产生的地址为: test4?callback=undefinedk&id=10
                    data: { id: 10 },
                    cache: false, //默认值true
                    dataType: "jsonp",
                    jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
                    jsonpCallback: function () { },
                    //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
                    //如果这里自定了jsonp的回调函数,则回调函数先起作用,后是success函数
                    success: function (data) {
                        alert(data.statu);
                        //alert(json.message);
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        alert(XMLHttpRequest.status);
                        alert(XMLHttpRequest.readyState);
                        alert(textStatus);
                    }
                });

这样的话,能正常返回。但是会先跑匿名函数,然后跑error函数。

 

posted @ 2014-12-26 10:56  ILONEY  阅读(340)  评论(0编辑  收藏