`

简化的原生ajax

阅读更多

/*

 *

 * path: seaAjax.js

 * author: eric_wang

 * date: 2014/10/22

 */

 

define(function(require,exports,module){

 

    var handpay=handpay||{"version":"v.1.0.0"};

 

    /**

     * @namespace handpay.ajax 对XMLHttpRequest请求的封装

     * @property success 请求失败的全局事件,function(String responseText,XMLHttpRequest xhr)

     * @property error 请求失败的全局事件,function(XMLHttpRequest xhr)

     * @property before 请求发送前触发的全局事件,function(XMLHttpRequest xhr)

     */

    handpay.ajax = handpay.ajax || {};

 

    /**

     * 发送一个ajax请求

     * @name handpay.ajax.request

     * @function

     * @grammar handpay.ajax.request(url[, options])

     * @param {string}  url 发送请求的url

     * @param {Object}  [options] 发送请求的选项参数

     * @config {String}     [method]            请求发送的类型。默认为GET

     * @config {String}     [dataType]            请求发送的类型。默认为GET

     * @config {Boolean} [async]            是否异步请求。默认为true(异步)

     * @config {Boolean} [cacheable]            是否缓存请求。默认为true(缓存)

     * @config {String}     [data]              需要发送的数据。

     * @config {Object}  [headers]           要设置的http request header

     * @config {String}     [username]          用户

     * @config {String}     [password]          密码

     * @config {Function} [success]       请求成功时触发,function(string responseText,XMLHttpRequest xhr)

     * @config {Function} [error]        请求失败时触发,function(XMLHttpRequest xhr)

     * @config {Function} [before]   发送请求之前触发,function(XMLHttpRequest xhr)

     * @config {Boolean} [noCache]          是否需要缓存,默认为true(缓存)

     * @meta standard

     * @see handpay.ajax.get,handpay.ajax.post,handpay.ajax.form

     *

     * @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象

     */

    handpay.ajax.request=function(url,options){

        options = options || {};

        var data = options.data || "";

        var async = !(options.async === false);// 是否异步请求。默认为true(异步)

        var cacheable = !(options.async === false);

        var username = options.username || "";

        var password = options.password || "";

        var method = (options.type || "GET").toUpperCase();

        var dataType = (options.dataType || "HTML").toUpperCase();

        var headers = options.headers || {};

        var success = options.success || "";

        var error = options.error || "";

        var before = options.before || "";

        var jsonp=options.jsonp || "jsonpcallback";  //jsonp的函数名称

        var jsonpCallback=options.jsonp||"";

        var charset=options.charset||"UTF-8";

        var xhr;

 

        /**HTML转义

         * @param {string} [str]  需要转义的字符串

         */

        function escape(str){

            return str

                .replace(/&/g,'&')

                .replace(/</g,'&lt;')

                .replace(/>/g,'&gt;')

                .replace(/"/g,'&quot;')

                .replace(/'/g,'&#39;');

        }

 

        function firedEvent(callback){

            switch(dataType){

                case "TEXT":

                    if(callback){

                        callback(escape(xhr.responseText),xhr);

                    }

                    break;

                case "JSON":

                    if(callback){

                        callback(parseJson(xhr.responseText),xhr);

                    }

                    break;

                case "HTML":

                default:

                    if(callback){

                        callback(xhr.responseText,xhr);

                    }

            }

        }

 

        function parseJson(str){

            if(typeof(str)==="object"){

                return str;

            }

            if(JSON){

                try{

                    return JSON.parse(str);

                }catch(e){

                    return (new Function("return "+str))();

                }

            }else{

                return (new Function("return "+str))();

            }

        }

 

        //状态报告

        function reportStatus(){

            if (xhr.readyState == 4) {

                var stat = xhr.status;

                if (stat == 200) {

                    firedEvent(success);

                } else {

                    // http://www.never-online.net/blog/article.asp?id=261

                    // case 12002: // Server timeout

                    // case 12029: // dropped connections

                    // case 12030: // dropped connections

                    // case 12031: // dropped connections

                    // case 12152: // closed by server

                    // case 13030: // status and statusText are unavailable

 

                    // IE error sometimes returns 1223 when it

                    // should be 204, so treat it as success

                    if ((stat >= 200 && stat < 300)

                        || stat == 304

                        || stat == 1223) {

                        firedEvent(success);

                    } else {

                        if(error){

                            error(xhr.responseText,xhr);

                        }

                    }

 

                    /*

                     * NOTE: Testing discovered that for some bizarre reason, on Mozilla, the

                     * JavaScript <code>XmlHttpRequest.onreadystatechange</code> handler

                     * function maybe still be called after it is deleted. The theory is that the

                     * callback is cached somewhere. Setting it to null or an empty function does

                     * seem to work properly, though.

                     *

                     * On IE, there are two problems: Setting onreadystatechange to null (as

                     * opposed to an empty function) sometimes throws an exception. With

                     * particular (rare) versions of jscript.dll, setting onreadystatechange from

                     * within onreadystatechange causes a crash. Setting it from within a timeout

                     * fixes this bug (see issue 1610).

                     *

                     * End result: *always* set onreadystatechange to an empty function (never to

                     * null). Never set onreadystatechange from within onreadystatechange (always

                     * in a setTimeout()).

                     */

                    window.setTimeout(

                        function() {

                            // 避免内存泄露

                            xhr.onreadystatechange = new Function();

                            if (async) {

                                xhr = null;

                            }

                        }, 0);

                }

            }

        }

 

        /**

         * 获取XMLHttpRequest对象

         *

         * @ignore

         * @return {XMLHttpRequest} XMLHttpRequest对象

         */

        function getXHR() {

            if (window.ActiveXObject) {

                try {

                    return new ActiveXObject("Msxml2.XMLHTTP");

                } catch (e) {

                    try {

                        return new ActiveXObject("Microsoft.XMLHTTP");

                    } catch (e) {}

                }

            }

            if (window.XMLHttpRequest) {

                return new XMLHttpRequest();

            }

        }

 

        //execute ajax request

        function executeXhr(callback) {

            xhr=getXHR();

            if(cacheable){

                try{

                    req.setRequestHeader("Cache-Control: no-store, no-cache, must-revalidate");

                    req.setRequestHeader("Connection","close");

                } catch(e){}

            }

            //

            var urlWithParam = url.split("?");//split the url in two parts

            var urlPrefix = urlWithParam[0];//the url

            var arg = urlWithParam[1];//the arguments

 

            if(method == "POST") {//若为post请求提交则修改url值

                url=urlPrefix;

            }

 

            if (username) {

                xhr.open(method, url, async, username, password);

            } else {

                xhr.open(method, url, async);

            }

 

            if (async) {

                xhr.onreadystatechange = callback;

            }

            xhr.setRequestHeader("Access-Control-Allow-Headers","X-Requested-With");

            xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");

            for (var key in headers) {

                if (headers.hasOwnProperty(key)) {

                    xhr.setRequestHeader(key, headers[key]);

                }

            }

 

            if(before){

                before.call(this,xhr);

            }

 

            if(method == "POST") {

                xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

                xhr.send(arg);

            } else {

                xhr.send();

            }

 

            if (!async) {

                if(callback){

                    callback.call(this);

                }

            }

        }

 

        function loadScript(callback){

            var head = document.head ||document.getElementsByTagName("head")[0]|| document.documentElement;

            var script = document.createElement("script");

            script.async = true;

            //if ( s.scriptCharset ) {

            script.charset = charset;

            //}

 

            script.src =url;

 

 

            // Attach handlers for all browsers

            script.onload = script.onreadystatechange = function( _, isAbort) {

 

                if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {

 

                    // Handle memory leak in IE

                    script.onload = script.onreadystatechange = null;

 

                    // Remove the script

                    if ( script.parentNode ) {

                        script.parentNode.removeChild( script );

                    }

 

                    // Dereference the script

                    script = null;

 

                    // Callback if not abort

                    if ( !isAbort ) {

 

                    }else{

                        if(error){

                            error();

                        }

                    }

                }

            };

 

            if(before){

                jsonpFired(before);

            }

 

            if(success){

                jsonpFired(success);

            }

            // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending

            // Use native DOM manipulation to avoid our domManip AJAX trickery

            head.insertBefore( script, head.firstChild );

            //}

        }

 

        //jsonp 数据获取

        function jsonpFired(callback){

            //console.log(" window."+jsonpCallback+"=function(data){data=(new Function('return data'))();callback(data)}");

            var fired=new Function("callbackfunction","parseJsonFun"," window."+jsonpCallback+"=function(data){data=parseJsonFun(data);callbackfunction(data);}");

            fired(callback,parseJson);

        }

 

 

        (function(){

            var callback = reportStatus;//default alert

            if(data||dataType==="JSONP"){

                if(url.indexOf("?")==-1){

                    url=url+"?";

                }else{

                    url+="&";

                }

                if(dataType==="JSONP"){

                    if(!jsonpCallback){// jsonpCallback 参数为空或者没传的时候 重新生成函数名称

                        jsonpCallback="handpayAjax"+(new Date().getTime());

                    }

                    url+=jsonp+"="+jsonpCallback+"&";

                }

                if(data){

                    try{

                        if(typeof(data)==="object"){ //如果data参数是json对象 就转为参数的链式结构

                            for(var i in data){

                                if(data.hasOwnProperty(i)){

                                    url+=i+"="+data[i]+"&";

                                }

                            }

                            if(!cacheable){

                                url+="t"+(new Date().getTime())+"=v1&";

                            }

                            url=url.substring(0,url.length-1);

                        }

 

                    }catch(e){

                        return null;

                    }

                }

            }

            /*encode URL with Chinese*/

            url = encodeURI(url);

            //alert(url);

            //execute the remote method

            if(dataType==="JSONP"){

                loadScript(callback);

            }else{

                executeXhr(callback);

            }

        })();

    };

 

 

    /**

     * 发送一个post请求

     * @name handpay.ajax.post

     * @function

     * @grammar handpay.ajax.post(url, data[, onsuccess])

     * @param {string}  url         发送请求的url地址

     * @param {string}  data        发送的数据

     * @param {Function} [onsuccess] 请求成功之后的回调函数,function(XMLHttpRequest xhr, string responseText)

     * @meta standard

     * @see handpay.ajax.get,handpay.ajax.request

     *

     * @returns {XMLHttpRequest}    发送请求的XMLHttpRequest对象

     */

    handpay.ajax.post = function (url, data, success) {

        var options={};

        options.method="POST";

        options.data=data;

        options.success=success;

        return handpay.ajax.request(

            url, options

        );

    };

 

 

 

 

    /**

     * 发送一个get请求

     * @name handpay.ajax.get

     * @function

     * @grammar handpay.ajax.get(url[, onsuccess])

     * @param {string}  url         发送请求的url地址

     * @param {Function} [success] 请求成功之后的回调函数,function(string responseText,XMLHttpRequest xhr)

     * @meta standard

     * @see handpay.ajax.post,handpay.ajax.request

     *

     * @returns {XMLHttpRequest}    发送请求的XMLHttpRequest对象

     */

    handpay.ajax.get = function (url,data,success) {

        var options={};

        options.method="GET";

        options.data=data;

        options.success=success;

        return handpay.ajax.request(url,options);

    };

 

    /**

     * 将一个表单用ajax方式提交

     * @name handpay.ajax.form

     * @function

     * @grammar handpay.ajax.form(form[, options])

     * @param {HTMLFormElement} form             需要提交的表单元素

     * @param {Object}  [options]                   发送请求的选项参数

     * @config {Boolean} [async]            是否异步请求。默认为true(异步)

     * @config {String}     [username]          用户

     * @config {String}     [password]          密码

     * @config {Object}     [headers]           要设置的http request header

     * @config {Function} [replacer]            对参数值特殊处理的函数,replacer(string value, string key)

     * @config {Function} [before]     发送请求之前触发,function(XMLHttpRequest xhr)

     * @config {Function} [success]        请求成功时触发,function(string responseText,XMLHttpRequest xhr)

     * @config {Function} [error]        请求失败时触发,function(XMLHttpRequest xhr)

 

     * @see handpay.ajax.request

     *

     * @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象

     */

    handpay.ajax.form = function (form, options) {

        options = options || {};

        var elements    = form.elements,

            len         = elements.length,

            method      = form.getAttribute('method'),

            url         = form.getAttribute('action'),

            replacer    = options.replacer || function (value, name) {

                    return value;

                },

            sendOptions = {},

            data = [],

            i, item, itemType, itemName, itemValue,

            opts, oi, oLen, oItem;

 

        /**

         * 向缓冲区添加参数数据

         * @private

         */

        function addData(name, value) {

            data.push(name + '=' + value);

        }

 

        // 复制发送参数选项对象

        for (i in options) {

            if (options.hasOwnProperty(i)) {

                sendOptions[i] = options[i];

            }

        }

 

        for (i = 0; i < len; i++) {

            item = elements[i];

            itemName = item.name;

 

            // 处理:可用并包含表单name的表单项

            if (!item.disabled && itemName) {

                itemType = item.type;

                itemValue = item.value;

 

                switch (itemType) {

                    // radio和checkbox被选中时,拼装queryString数据

                    case 'radio':

                    case 'checkbox':

                        if (!item.checked) {

                            break;

                        }

 

                    // 默认类型,拼装queryString数据

                    case 'textarea':

                    case 'text':

                    case 'password':

                    case 'hidden':

                    case 'select-one':

                        addData(itemName, replacer(itemValue, itemName));

                        break;

 

                    // 多行选中select,拼装所有选中的数

                    case 'select-multiple':

                        opts = item.options;

                        oLen = opts.length;

                        for (oi = 0; oi < oLen; oi++) {

                            oItem = opts[oi];

                            if (oItem.selected) {

                                addData(itemName, replacer(oItem.value, itemName));

                            }

                        }

                        break;

                }

            }

        }

 

        // 完善发送请求的参数选项

        sendOptions.data = data.join('&');

        sendOptions.method = form.getAttribute('method') || 'POST';

 

        // 发送请

        return handpay.ajax.request(url, sendOptions);

    };

    module.exports=handpay.ajax;

});

分享到:
评论

相关推荐

    原生ajax代码实现异步提交

    原生Ajax技术是Web开发中的一个关键组成部分,它允许网页在不刷新整个页面的情况下与服务器进行数据交互,实现异步通信。在这个场景中,我们讨论的是如何使用原生JavaScript代码来实现一个简单的异步提交功能,例如...

    原生AJAX或jQuery实现二级联动选择以及解析XML和JSON数据格式

    在IT行业中,尤其是在Web开发领域,原生AJAX(Asynchronous JavaScript and XML)和jQuery库是经常被用来创建动态交互式用户体验的技术。本篇博客主要探讨如何利用这两者实现二级联动选择,即当用户在一级选择中作出...

    JavaScript案例-原生ajax

    原生Ajax虽然功能强大,但代码相对复杂,因此在实际开发中,开发者往往会选择jQuery、axios、fetch等库或API来简化工作。然而,理解原生Ajax的工作原理对解决特定问题和优化性能具有重要意义。在"JavaScript案例-...

    AjaxDemo供学习

    2. **jQuery的Ajax方法**:简化原生Ajax调用的库,如`$.ajax()`, `$.get()`, `$.post()`等。 3. **JSON数据格式**:Ajax传输数据的常见格式,轻量级且易于处理。 4. **Partial Rendering**:只更新页面的部分区域,...

    原生Ajax 和jQuery Ajax的区别示例分析

    - **简化操作:** 通过jQuery封装的$.ajax方法,大大简化了原生Ajax的代码,提高了开发效率。 - **易用性:** 提供了更多的默认设置,让开发者不需要编写大量的配置代码。 - **跨浏览器兼容:** jQuery内部对Ajax的...

    基于原生ajax与封装的ajax使用方法(详解)

    通过原生Ajax,我们可以实现页面的异步数据获取,而通过封装Ajax函数,可以简化代码并提高复用性。在没有真实后端接口的情况下,使用Express和Node.js可以方便地创建模拟接口,供前端进行开发和测试。在实际项目中,...

    Javascript原生ajax请求代码实例

    然而,现代Web开发中,通常会使用像jQuery、axios或fetch这样的库来简化Ajax操作,因为它们提供了更多的功能和更好的浏览器兼容性。但了解原生实现有助于理解这些库的工作原理,对于进行更底层的问题排查和优化很有...

    javascript原生ajax写法分享_.docx

    JavaScript中的AJAX(Asynchronous JavaScript and XML)是一种在无需刷新整个...随着技术的发展,现在更多地使用fetch API或jQuery等库来简化这一过程,但在理解基础的AJAX工作原理时,原生实现仍然是非常有价值的。

    javascript实现原生ajax的几种方法介绍

    虽然现在有许多流行的JavaScript框架和库(如jQuery)简化了AJAX的实现,但在一些轻量级或特定场景下,了解如何用原生JavaScript实现AJAX也是非常有价值的。接下来,我们将详细介绍几种使用原生JavaScript实现AJAX的...

    使用jQuery简化Ajax 开发.pdf

    为了直观地展示jQuery如何简化代码,我们可以比较一下使用原生JavaScript和DOM操作与使用jQuery实现相同功能的例子。假设我们需要为页面上某个区域内的所有链接添加点击事件,询问用户是否确认访问链接。使用传统的...

    比较完整的原始ajax写法

    在实际开发中,原生Ajax可能比较繁琐,因此现在常常使用像jQuery的`$.ajax()`或fetch API这样的工具来简化操作。 在压缩包文件名称列表中的"ajaxDemo"可能是包含了一个简单的Ajax请求示例的文件,可能包含HTML、...

    使用_jQuery_简化_Ajax_开发.txt

    ### 使用jQuery简化Ajax开发 #### 一、简介与背景 jQuery 是一款流行的 JavaScript 库,由 John Resig 在 2006 年创建。它极大地简化了 JavaScript 的使用方式,尤其是在处理 DOM(Document Object Model)操作...

    ajax ext 表格数据导出

    在Web开发中,数据的导入导出功能是十分..."grid2excel"这一功能的实现,简化了开发流程,使得这个过程变得更加简单和高效。在实际开发中,根据具体项目需求,可能还需要考虑兼容性、错误处理以及用户体验优化等问题。

    zk语言开发基于Ajax的东西

    它简化了Ajax的复杂性,让开发者可以专注于业务逻辑,而不是底层网络通信的细节。 在"zk-bin-3.6.3"这个压缩包中,包含的是ZK框架的3.6.3版本。这个版本可能包含了ZK运行所需的JAR文件、文档、示例代码和其他相关...

    使用jQuer简化Ajax开发-Ajax开发入门.pdf

    【jQuery简化Ajax开发】 jQuery是一个JavaScript库,它的主要目标是简化JavaScript和AJAX的编程,使得开发者能够以更简洁的方式处理DOM操作和异步数据交互。由John Resig创建于2006年,jQuery迅速成为了JavaScript...

    使用jQuer简化Ajax开发——Ajax开发入门.docx

    jQuery 是一个强大的 JavaScript 库,它极大地简化了 DOM 操作、事件处理、动画效果以及Ajax交互等任务。本篇文章将详细介绍如何使用jQuery来简化Ajax开发,帮助初学者快速入门。 1. **DOM操作的简化** 在jQuery中...

    tomcat-servlet-ajax最基础例子

    这里以jQuery为例,它简化了Ajax操作。 ```html &lt;!DOCTYPE html&gt; &lt;script src="https://code.jquery.com/jquery-3.6.0.min.js"&gt;&lt;/script&gt; $(document).ready(function() { $("#btnAjax").click(function() {...

    原生ajax处理json格式数据的实例代码

    原生AJAX处理JSON格式数据的实例代码主要涉及到Web开发中客户端与服务器端数据交互的知识点。AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个页面的情况下,能够更新部分网页的技术。JSON...

    原生JS写Ajax的请求函数功能

    它们对"ajax.send"进行了封装,简化了代码。"ajax.get"方法会将参数拼接为查询字符串,并添加到URL中。"ajax.post"方法会将数据拼接为application/x-www-form-urlencoded格式的字符串,并作为请求体发送。 在使用...

    Java学习Ajax的小例子

    **Ajax(Asynchronous JavaScript and XML)**是一种在无需重新加载整个网页的情况...通过深入学习和实践,你可以掌握更高级的Ajax技术,如使用jQuery或Vue.js等库简化Ajax操作,以及更复杂的服务器端逻辑和数据处理。

Global site tag (gtag.js) - Google Analytics