`
java_ahhhy8618
  • 浏览: 2333 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

AJAX跨域请求之JSONP实现

阅读更多
AJAX自2004年前后兴盛起来一直就被大家所追捧着,生命力极其旺盛!AJAX的兴起也带了来一次互联网的革命,众多基于AJAX的网站一夜间都纷纷冒了出来。以GOOGLE为首的各大网站均开始了新一轮的技术竞争,GMIAL的出现使大家感受到了AJAX所带来的好处,尝到了甜头。他的异步请求,无页面刷新可以很直观的被大家看到操作后的一些效果;再也不用等在电脑前看着空白页面发呆了。俗话说的好:人无完人!何况是由人所开发的东西即是如此。AJAX也有一些自身的不足之处,大家可以随便从网上搜一下就可以看到很多关于AJAX的一些缺点,如:不能后退,请求进跨域等等。所谓网络上所说的AJAX七综罪!

     关于AJAX的事事非非,我不去评论。什么事情都有好的一面和坏的一面,这就要看大家去怎么理解和使用了!现在我要说的是关于AJAX跨域时所出现的问题。现在我们解决AJAX跨域时所用到的一些方法有:iframe,JSONP(script标签请求),flash,window.name属性进行跨域(我没有测试过,如果感兴趣可以看一下克军写的一个例子)。我接触的也不是很多,如果有哪里说的不全请大家多多谅解!

     下面就来说一下关于JSONP的跨域。JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。这种跨域的通讯方式称为JSONP。很明显,JSONP是一种脚本注入(Script Injection)行为,需要特别注意其安全性。

     如果我们要用JSONP做一个跨域请求,需求如下:

     1、现在有两个站点,分别是:http://www.google.com/ 和 http://www.sina.com.cn

     2、现在我们要从google中访问sina中的某个请求

     客户端代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Test Jsonp</title>
    <script type="text/javascript">
       // 事先定义好的回调函数
            function jsonpCallback(result)
            {
                alert(result.msg);
            }
        </script>
    <script type="text/javascript" src="http://www.sina.com.cn/jsonServerResponse?jsonp=jsonpCallback"></script>
</head>
<body>
</body>
</html>

     此段代码中标签script是注入标签,其目的就是当<script>加入到页面后便开始利用其src属性对sina服务器端发起请求。其中请求地址中的“jsonp=jsonpCallback”就是回调函数(callback),当服务器端获取到请求地址信息后再将其参数“jsonp=”后的回调函数原封不动的写回页面的<script>标签中,但此时可以在回调函数中将其所需要的参数传入(json或是其他形式)。但是在回写此函数之前,这个回调函数要先被定义于页面否则会报错误!

     如果每次做AJAX跨域请求时都要这样做的话,那就也太麻烦了。能不能将这个回调函数一起写入某个JS文件呢?当在执行请求时,动态的在页面上进行如此的操作呢?答案是YES!下面就来看一个定义的JSONP方法:

// 建立JSON请求
var setJSONRequest = function(){
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    var fun = this.setRandomFun();  // 获取随机函数名
    var _this = this;
    var param = '';

    // 拼接请求信息
    for(var i in this.param){
        if(param == ''){
            param = i+'='+this.param[i];
        }else{
            param+= '&'+i+'='+this.param[i];
        }
    }

    script.type = 'text/javascript';
    script.charset = 'utf-8';

    if(head){
        head.appendChild(script);
    }else{
        document.body.appendChild(script);
    }

    // data:为回调函数所需要传入的参数
    // 定义页面中的回调函数,如例子中的“jsonpCallback()”方法
    window._$JSON_callback[fun.id] = function(data){
        _this.callback.success(data);

        // 隔100毫秒后删除随机函数和script标签
        setTimeout(function(){
            delete window._$JSON_callback[fun.id];
            script.parentNode.removeChild(script);
        }, 100);
    };

    // 页面中载入些标签后,便开始通过src的属性向服务器端进行请求操作
    script.src = this.url+'?callback='+fun.name+'&'+param;
};

// 生成随机JSONP回调函数
var setRandomFun = function(){
    var id = '';

    do{
        id = '$JSON'+Math.floor(Math.random()*10000);
    }while(window._$JSON_callback[id])

    return{
        id : id,
        name : 'window._$JSON_callback.'+id
    }
};



     当执行JSONP请求时,此方法会自动在页面中生成一个用以请求服务的script标签;服务端接到此请求信息后再将callback回调函数写到页面并传入相应的参数,便完成了一次AJAX的跨域请求。同时又将刚才所定义的函数和script请求标签删除。这样的话,以后如果再需要JSONP请求时就不需要都在页面中定义N多的回调函数了,可以省去了不好体力活儿。每次请求时只需要将随机生成的回调函数以请求地址的形式一起传入服务器端,服务器端通过判断来再将回调写入页面来完成请求的回调。

     下面是一下相对完整的AJAX请求,其中包括了XHR和JSONP的请求判断:

// 定义AJAX跨域请求的JSON
(function(){
    if(typeof window.$JSON== 'undefined'){
        window.$JSON= {};
    };

    $JSON._ajax = function(config){
        config = config[0] || {};
        this.url = config.url || '';
        this.type = config.type || 'xhr';
        this.method = (this.type == 'json') ? 'GET' : config.method.toUpperCase() || 'GET';
        this.param = config.param || null;
        this.callback = config.callback || {};
        this.XHR = null;

        if(typeof window._$JSON_callback == 'undefined'){
            window._$JSON_callback = {};
        }

        this._createRequest();
    };

    $JSONP._ajax.prototype = {

        // 缓存XHR请求,再次再调用时不再进行判断
        _createXHR : function(){
            var methods = [
                function(){ return new XMLHttpRequest(); },
                function(){ return new ActiveXObject('Msxml2.XMLHTTP'); },
                function(){ return new ActiveXObject('Microsoft.XMLHTTP'); }
            ];
            for(var i = 0, l = methods.length; i < l; i++){
                try{
                    methods[i]();
                }catch(e){
                    continue;
                }
                this._createXHR = methods[i];
                return methods[i]();
            }
        },

        // 建立XHR请求
        _createRequest : function(){
            return (this.type == 'json') ? this._setJSONRequest() : this._setXHRRequest();
        },

        _setXHRRequest : function(){
            var _this = this;
            var param = '';

            for(var i in this.param){
                if(param == ''){
                    param = i+'='+this.param[i];
                }else{
                    param+= '&'+i+'='+this.param[i];
                }
            }

            this.XHR = this._createXHR();
            this.XHR.onreadystatechange = function(){
                if(_this.XHR.readyState == 4 && _this.XHR.status == 200){
                    _this.callback.success(_this.XHR.responseText);
                }else{
                    _this.callback.failure('重新操作');
                }
            };

            this.XHR.open(this.method, this.url, true);
            this.XHR.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");
            this.XHR.send(param);
        },

        // 建立JSON请求
        _setJSONRequest : function(){
            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');
            var fun = this._setRandomFun();
            var _this = this;
            var param = '';

            for(var i in this.param){
                if(param == ''){
                    param = i+'='+this.param[i];
                }else{
                    param+= '&'+i+'='+this.param[i];
                }
            }

            script.type = 'text/javascript';
            script.charset = 'utf-8';
            if(head){
                head.appendChild(script);
            }else{
                document.body.appendChild(script);
            }

            // data:为回调函数所需要传入的参数
            // 定义页面中的回调函数,如例子中的“jsonpCallback()”方法
            window._$JSON_callback[fun.id] = function(data){
                _this.callback.success(data);
                setTimeout(function(){
                    delete window._$JSON_callback[fun.id];
                    script.parentNode.removeChild(script);
                }, 100);
            };

            script.src = this.url+'?callback='+fun.name+'&'+param;
        },

        // 生成随机JSON回调函数
        _setRandomFun : function(){
            var id = '';
            do{
                id = '$JSON+Math.floor(Math.random()*10000);
            }while(window._$JSON_callback[id])
            return{
                id : id,
                name : 'window._$JSON_callback.'+id
            }
        }
    };
    window.$JSON.ajax = function(){
        return new $JSON._ajax(arguments);
    }
})();



     在调用此函数进行执行时,只需new一个ajax()函数出来并传入相应参数即可。
var ajax = new $JSON.ajax({
    url : 'http://www.sina.com.cn/xxx.jsp',
    type : 'json',
    method : 'get',
    callback : {
        success : function(info){
            alert(info);
        },

        failure : function(error){
            alert(errow);
        }
    }
});



      通过初始化“$JSON.ajax()”函数便完成了一个JSONP的异步跨域请求,这只是一个简单的实现。更复杂的内容就需要大家来进行挖掘了。

原文出处http://www.cnblogs.com/Guazi-JS/archive/2010/05/01/1725530.html
分享到:
评论

相关推荐

    ajax跨域请求jsonp前后台代码

    基于ajax方式的跨域请求jsonp的前后台代码

    jsonpajax跨域请求

    "jsonp跨域请求"可能是服务器返回的示例数据,模拟了JSONP的跨域请求过程。 总结,JSONP和CORS是解决JavaScript跨域问题的两种主要方法,它们各有优缺点,适用于不同的场景。JSONP简单易用,但安全性较低;CORS则更...

    Ajax跨域请求解决方案-JSONP

    总的来说,JSONP是Ajax跨域请求的一种实用解决方案,尤其适用于只支持GET请求且不涉及复杂交互的场景。但是,它也有一些局限性,比如不支持POST请求、无法控制HTTP头部、无错误处理机制等。因此,在现代Web开发中,...

    利用JQuery jsonp实现Ajax跨域请求json数据

    本篇文章将详细讲解如何利用jQuery的jsonp方法实现Ajax跨域请求,以及如何在服务器端使用.Net的*.handler和WebService来返回JSON数据。 首先,理解JSONP的基本原理。JSONP是一种非官方的协议,通过动态创建`...

    html通过 ajax jsonp跨域请求接收和传送数据

    **AJAX和JSONP跨域请求的实现过程** 1. **AJAX跨域**: 通常,AJAX请求受到同源策略限制。为实现跨域,我们可以使用CORS(Cross-Origin Resource Sharing)机制。服务器需要在响应头中添加`Access-Control-Allow-...

    ajax 跨域请求问题 jquery jsonp

    **Ajax跨域请求问题与jQuery JSONP解析** 在Web开发中,Ajax技术被广泛用于实现页面的异步更新,但浏览器的同源策略(Same-Origin Policy)限制了Ajax请求只能向同源(协议、域名、端口均相同)的服务器发送。这在...

    ajax跨域CORS方案 JSONP跨域请求方案.zip

    在Web开发中,跨域(Cross-Origin)是一个常见的问题,特别是在使用Ajax进行异步数据交互时。跨域限制是浏览器为了安全原因而设置的一种机制,防止恶意网站通过脚本访问其他站点的数据。本文将深入探讨两种主要的...

    PHP AJAX JSONP实现跨域请求使用范例_ajax如何解决跨域请求

    PHP AJAX JSONP 实现跨域请求使用实例 在 Web 开发中,跨域请求是指从一个域名下的页面请求另一个域名下的资源,这种情况下,浏览器会限制这种请求,以防止恶意攻击。JSONP(JSON with Padding)是一种解决跨域请求...

    解决ajax跨域请求问题

    本文将深入探讨如何解决Ajax跨域请求的问题。 首先,理解“同源策略”是解决问题的关键。同源策略是浏览器为了保障网络安全而设定的一种机制,它禁止了一个源的文档或脚本访问另一个源的属性,这里的“源”指的是...

    Jquery跨域Ajax请求测试

    除了JSONP,还可以通过CORS(Cross-Origin Resource Sharing,跨源资源共享)来实现跨域请求。CORS需要服务端支持,在响应头中添加`Access-Control-Allow-Origin`字段,指定允许哪些源进行跨域请求。在jQuery中,...

    ajax跨域请求WebService.asmx

    【Ajax跨域请求WebService.asmx】是一个常见的Web开发技术应用场景,主要涉及到JavaScript的Ajax技术、C#编程语言以及ASP.NET的WebService组件。Ajax(Asynchronous JavaScript and XML)是一种在不刷新整个页面的...

    ajax跨域请求

    本篇文章将通过一个具体的示例(JSP页面+后台实例)来详细介绍如何实现AJAX跨域请求。 #### 二、同源策略概述 同源策略(Same-origin policy)是浏览器的一项安全措施,用于限制一个源上的网页脚本与另一个源上的...

    AJAX跨域请求之JSONP获取JSON数据

    JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

    ajax处理跨域请求

    这里将详细讲解如何通过jQuery的AJAX实现跨域请求。 首先,了解什么是CORS(Cross-Origin Resource Sharing,跨源资源共享)。CORS是一种机制,它使用额外的HTTP头来告诉浏览器允许一个域上的网页访问另一个域上的...

    ajax跨域解决办法

    6. **Domain属性(仅限子域)**:在cookies中设置`domain`属性可以实现跨子域共享,但这仅限于同一主域下的子域名之间,对AJAX跨域请求帮助有限。 在实际应用中,开发者通常根据项目需求和服务器环境选择合适的跨域...

    Ajax + Servlet 跨域访问(Jsonp技术)

    在这种背景下,Jsonp(JSON with Padding)应运而生,它是一种允许跨域数据交互的技术,特别适用于Ajax请求。 Jsonp的核心思想是利用HTML `&lt;script&gt;`标签的src属性可以不受同源策略限制的特性。它的工作流程如下: ...

    使用JSONP完成HTTP和HTTPS之间的跨域访问

    这一步对于简单的跨域请求不是必需的。 2. **配置Tomcat以支持HTTPS**: - 在Tomcat的`conf/server.xml`文件中,找到或添加`&lt;Connector&gt;`标签以启用HTTPS连接: ```xml maxThreads="150" scheme=...

    JSONP实现Ajax跨域访问

    ### JSONP实现Ajax跨域访问 #### 一、引言 JSONP(JSON with Padding)是一种用于解决跨域数据访问的技术。由于同源策略(Same-Origin Policy)的存在,JavaScript/Ajax只能请求同源的资源,这给需要跨域访问数据...

Global site tag (gtag.js) - Google Analytics