跨域通信的解决方案JSONP

在web2.0时代,熟练的使用ajax是每个前端攻城师必备的技能。然而由于受到浏览器的限制,ajax不允许跨域通信。

JSONP就是就是目前主流的实现跨域通信的解决方案。

虽然在在jquery中,我们可以通过$.ajax的dataType设置为jsonp来调用jsonp,但是jsonp和ajax的实现原理一个关系都木有。jsonp主要是通过script可以链接远程url来实现跨域请求的。如:

<script src="http://jsonp.js?callback=xxx"></script>

callback定义了一个函数名,而远程服务端通过调用指定的函数并传入参数来实现传递参数。

搜索了网上好多文章,他们实现方法都过于简单,要实际应用还要多加修改,我在这里封装了一个对象,可以直接运用于实际操作。

var JSONP = {
    // 获取当前时间戳
    now: function() {
        return (new Date()).getTime();
    },

    // 获取16位随机数
    rand: function() {
        return Math.random().toString().substr(2);
    },

    // 删除节点元素
    removeElem: function(elem) {
        var parent = elem.parentNode;
        if(parent && parent.nodeType !== 11) {
            parent.removeChild(elem);
        }
    },

    // url组装
    parseData: function(data) {
        var ret = "";
        if(typeof data === "string") {
            ret = data;
        }
        else if(typeof data === "object") {
            for(var key in data) {
                ret += "&" + key + "=" + encodeURIComponent(data[key]);
            }
        }
        // 加个时间戳,防止缓存
        ret += "&_time=" + this.now();
        ret = ret.substr(1);
        return ret;
    },

    getJSON: function(url, data, func) {
        // 函数名称
        var name;

        // 拼装url
        url = url + (url.indexOf("?") === -1 ? "?" : "&") + this.parseData(data);

        // 检测callback的函数名是否已经定义
        var match = /callback=(\w+)/.exec(url);
        if(match && match[1]) {
            name = match[1];
        } else {
            // 如果未定义函数名的话随机成一个函数名
            // 随机生成的函数名通过时间戳拼16位随机数的方式,重名的概率基本为0
            // 如:jsonp_1355750852040_8260732076596469
            name = "jsonp_" + this.now() + ‘_‘ + this.rand();
            // 把callback中的?替换成函数名
            url = url.replace("callback=?", "callback="+name);
            // 处理?被encode的情况
            url = url.replace("callback=%3F", "callback="+name);
        }

        // 创建一个script元素
        var script = document.createElement("script");
        script.type = "text/javascript";
        // 设置要远程的url
        script.src = url;
        // 设置id,为了后面可以删除这个元素
        script.id = "id_" + name;

        // 把传进来的函数重新组装,并把它设置为全局函数,远程就是调用这个函数
        window[name] = function(json) {
            // 执行这个函数后,要销毁这个函数
            window[name] = undefined;
            // 获取这个script的元素
            var elem = document.getElementById("id_" + name);
            // 删除head里面插入的script,这三步都是为了不影响污染整个DOM啊
            JSONP.removeElem(elem);
            // 执行传入的的函数
            func(json);
        };

        // 在head里面插入script元素
        var head = document.getElementsByTagName("head");
        if(head && head[0]) {
            head[0].appendChild(script);
        }
    }
};

实现过程基本写在注释里啦,自己看。调用的方法跟jQuery基本一样。如:

var data = {
            from: "北京",
            count: 27,
            output: "json",
            callback: "?"
        }
JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp", data, function(json) {console.log(json)});

当然要这么写也行:

JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp?from=北京&count=27&output=json&callback=?", null, function(json) {console.log(json)});

至于服务端的实现,那就比较简单了,以php为例:

$callback = !empty($_GET[‘callback‘]) ? $_GET[‘callback‘] : ‘callback‘;
echo $callback.‘( .json_encode( $data ).‘)‘;
时间: 2024-11-02 11:22:11

跨域通信的解决方案JSONP的相关文章

使用 JSONP 实现跨域通信

简介 Asynchronous JavaScript and XML (Ajax) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术.Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索.使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器.Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序. 不过,由于受到浏览器的限制

使用 JSONP 实现跨域通信,第 1 部分: 结合 JSONP 和 jQuery 快速构建强大的 mashup

http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/ 简介 Asynchronous JavaScript and XML (Ajax) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术.Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索.使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器.Ajax 也是许

理解跨域及常用解决方案

跨域,相信大家无论是在工作中还是在面试中经常遇到这个问题,常常在网上看到别人所整理的一些方法,看似知道是怎么回事,但如果没有动手实践过,总觉得自己没有真正的掌握,在这里,通过自己认真思考整理一些常用的方法. 跨域的产生 不用多讲,作为一名前端开发人员,相信大家都知道跨域是因为浏览器的同源策略所导致的.所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源.浏览器引入同源策略主要是为了防止XSS,CSRF攻击. CSRF(Cross-site reque

【JavsScript】父子页面之间跨域通信的方法

由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时还是有些不够明白的地方,深入了解之后,这里给大家补充一点更具体的做法. 先来看看哪些情况下才存在跨域的问题: 其中编号6.7两种情况同属于主域名相同的情况,可以设置domain来解决问题,今天就不讨论这种情况了. 对于其他跨域通信的问题,我想又可以分成两类: 其一(第一种情况)是a.com下面的a.

【JavaScript】父子页面之间跨域通信的方法

由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时还是有些不够明白的地方,深入了解之后,这里给大家补充一点更具体的做法. 先来看看哪些情况下才存在跨域的问题: 其中编号6.7两种情况同属于主域名相同的情况,可以设置domain来解决问题,今天就不讨论这种情况了. 对于其他跨域通信的问题,我想又可以分成两类: 其一(第一种情况)是a.com下面的a.

跨域通信/跨域上传浅析

web项目跨域问题主要包括跨域通信和跨域上传,下面对这两方面分别做一个分析,具体项目中用哪个方案要看项目具体需求. 跨域通信 jsonp hash server proxy window.name cors postmessage redirect jsonp 原理:发起一个GET请求,回调函数带到请求参数中,把数据发送过去 坏处:服务器需要支持jsoncallback参数 好处:业界比较通用的方案,包括打点等操作都可以用类似技术 浏览器支持:chrome/firefox/safari/oper

跨域通信方法总结

本文总结了5种较常见的跨域通信方法,如下: 1)jsonp 2)CORS(Cross OriginResource Sharing,跨源资源共享) 3)主域相同可以设置document.domain 4)利用window.name实现跨域 5)利用window.name实现跨域 jsonp 讲解jsonp之前先看一个例子:假设域A.com上有一个页面a.html,代码如下: var dosomething= function(data){ alert('我是A.com域上的页面,可以被跨域的re

使用 &lt;Iframe&gt;实现跨域通信

什么是iframe iframe就是我们常用的iframe标签:<iframe>.iframe标签是框架的一种形式,也比较常用到,iframe一般用来包含别的页面,例如我们可以在我们自己的网站页面加载别人网站或者本站其他页面的内容. iframe的用法有很多,接下来说一下iframe的其中一个比较实用的用法----跨域通信 假设现在有两个系统A,B:A系统的某个页面有一部分显示的内容是B系统的,怎么办? <div class="modal-body" id="

前端筑基篇(一)-&gt;ajax跨域原理以及解决方案

说明 跨域主要是由于浏览器的“同源策略”引起,分为多种类型,本文主要探讨Ajax请求跨域问题 前言 参考来源 什么是跨域 ajax跨域的表现 跨域的原理 如何解决跨域问题 JSONP方式解决跨域问题 CROS解决跨域问题 CROS请求原理 PHP后台配置 JAVA后台配置 .NET后台配置 FAQ multi value '*,*' 的问题 前言 强烈推荐阅读参考来源中的文章,能够快速帮助了解跨域的原理 参考来源 本文参考了以下来源 浏览器同源政策及其规避方法(阮一峰) 跨域资源共享 CORS