资讯专栏INFORMATION COLUMN

从jquery,zepto中提取的90行代码实现一个完整的ajax

yeooo / 3033人阅读

摘要:请求地址,异步同步,会锁死浏览器,并且方法会报浏览器警告提交方法提交数据账号密码返回数据类型成功返回回调错误信息回调请求超时

function ajax(options) {
    function empty() {}

    function obj2Url(obj) {
        if (obj && obj instanceof Object) {
            var arr = [];
            for (var i in obj) {
                if (obj.hasOwnProperty(i)) {
                    if (typeof obj[i] == "function") obj[i] = obj[i]();
                    if (obj[i] == null) obj[i] = "";
                    arr.push(escape(i) + "=" + escape(obj[i]));
                }
            }
            return arr.join("&").replace(/%20/g, "+");
        } else {
            return obj;
        }
    };
    var opt = {
        url: "", //请求地址
        sync: true, //true,异步 | false 同步,会锁死浏览器,并且open方法会报浏览器警告
        method: "GET", //提交方法
        data: null, //提交数据
        username: null, //账号
        password: null, //密码
        dataType: null, //返回数据类型
        success: empty, //成功返回回调
        error: empty, //错误信息回调
        timeout: 0, //请求超时ms
    };
    for (var i in options) if (options.hasOwnProperty(i)) opt[i] = options[i];
    var accepts = {
        script: "text/javascript, application/javascript, application/x-javascript",
        json: "application/json",
        xml: "application/xml, text/xml",
        html: "text/html",
        text: "text/plain"
    };
    var abortTimeout = null;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            xhr.onreadystatechange = empty;
            clearTimeout(abortTimeout);
            var result,dataType, error = false;
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == "file:")) {
                if (xhr.responseType == "arraybuffer" || xhr.responseType == "blob") {
                    result = xhr.response;
                } else {
                    result = xhr.responseText;
                    dataType = opt.dataType ? opt.dataType : xhr.getResponseHeader("content-type").split(";", 1)[0];
                    for (var i in accepts) {
                        if (accepts.hasOwnProperty(i) && accepts[i].indexOf(dataType) > -1) dataType = i;
                    }
                    try {
                        if (dataType == "script") {
                            eval(result);
                        } else if (dataType == "xml") {
                            result = xhr.responseXML
                        } else if (dataType == "json") {
                            result = result.trim() == "" ? null : JSON.parse(result)
                        }
                    } catch (e) {
                        opt.error(e, xhr);
                        xhr.abort();
                    }
                }
                opt.success(result, xhr);
            } else {
                opt.error(xhr.statusText, xhr);
            }
        }
    };
    if (opt.method == "GET") {
        var parse = opt.url.parseURL();
        opt.data = Object.assign({}, opt.data, parse.params);
        opt.url = parse.pathname + "?" + obj2Url(opt.data);
        opt.data = null;
    }
    xhr.open(opt.method, opt.url, opt.sync, opt.username, opt.password);
    if (opt.method == "POST") xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    if (opt.timeout > 0) {
        abortTimeout = setTimeout(function() {
            xhr.onreadystatechange = empty
            xhr.abort();
            opt.error("timeout", xhr);
        }, opt.timeout)
    }
    xhr.send(opt.data ? obj2Url(opt.data) : null);
}

test

ajax({
    url:"/url",
    data:{
        i:new Date().getTime(),
    },
    success:function(data,xhr){
        console.log(data,xhr);
    },
    error:function(err,xhr){
        console.log(err,xhr);
    }
});

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91194.html

相关文章

  • Zepto 源码分析 1 - 进入 Zepto

    摘要:选择的理由是一个用于现代浏览器的与大体兼容的库。环境搭建分析环境的搭建仅需要一个常规页面和原始代码一个常规页面打开的首页即可,在开发人员工具中即可使用原始代码本篇分析的代码参照,进入该代码分支中即可。 选择 Zepto 的理由 Zepto is a minimalist JavaScript library for modern browsers with a largely jQue...

    Aklman 评论0 收藏0
  • JQuery使用总结

    摘要:目前接触最多的页面开发,基本还是使用的。主要原因基于操作方便页面简单兼容良好新手多没有能配合使用其他方案的人。,是的核心理念。 目前接触最多的页面开发,基本还是使用 JQuery 的。主要原因基于:操作方便;页面简单;兼容良好;新手多……没有能配合使用其他方案的人。因此,本篇文章就是写着玩加吐点槽的。 Write Less,Do More是JQuery的核心理念。所以你们就不要在工作中...

    tomlingtm 评论0 收藏0
  • JQuery使用总结

    摘要:目前接触最多的页面开发,基本还是使用的。主要原因基于操作方便页面简单兼容良好新手多没有能配合使用其他方案的人。,是的核心理念。 目前接触最多的页面开发,基本还是使用 JQuery 的。主要原因基于:操作方便;页面简单;兼容良好;新手多……没有能配合使用其他方案的人。因此,本篇文章就是写着玩加吐点槽的。 Write Less,Do More是JQuery的核心理念。所以你们就不要在工作中...

    dreambei 评论0 收藏0
  • JavaScript Promise启示录

    摘要:近几年随着开发模式的逐渐成熟,规范顺势而生,其中就包括提出了规范,完全改变了异步编程的写法,让异步编程变得十分的易于理解。最后,是如此的优雅但也只是解决了回调的深层嵌套的问题,真正简化异步编程的还是,在端,建议考虑。 本篇,简单实现一个promise,主要普及promise的用法。 一直以来,JavaScript处理异步都是以callback的方式,在前端开发领域callback机制...

    Juven 评论0 收藏0
  • [转载·JS] JavaScript Promise启示录

    摘要:近几年随着开发模式的逐渐成熟,规范顺势而生,其中就包括提出了规范,完全改变了异步编程的写法,让异步编程变得十分的易于理解。最后,是如此的优雅但也只是解决了回调的深层嵌套的问题,真正简化异步编程的还是,在端,建议考虑。 前段时间频频看到Promise这个词,今天发现腾讯AlloyTeam写得这篇很赞,遂转之。 原文链接 本篇,主要普及promise的用法。 一直以来,JavaScrip...

    Lyux 评论0 收藏0

发表评论

0条评论

yeooo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<