资讯专栏INFORMATION COLUMN

原生js实现Ajax,JSONP

mating / 3022人阅读

摘要:内部的几个执行步骤创建对象设置请求头连接服务器设置回调发送数据在回调函数中获取数据利用标签可以跨域请求资源解决跨域问题。

Ajax内部的几个执行步骤

创建XMLHttpRequest对象(new XMLHttpRequest())

设置请求头(setRequestHeader)

连接服务器(open())

设置回调(onreadyStateChange)

发送数据(send())

在回调函数中获取数据

JSONP

利用script标签可以跨域请求资源解决跨域问题。详细解释可以看彻底弄懂跨域问题

前端代码
/*
* 原生js实现Ajax
* */

function Ajax(params) {
    params = params || {};
    params.data = params.data || {};
    var _json = params.jsonp ? jsonp(params): json(params); // 判断是json还是jsonp
    function json(params) { // 普通请求
        params.type = (params.type || "GET").toUpperCase(); // 设置请求默认类型
        var urlData = formatParams(params.data); // 对数据进行格式化
        var xhr = null; // 对xhr进行初始化
        if (window.XMLHttpRequest) {
            xhr = new window.XMLHttpRequest();
        } else {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        var headers = params.headers || {};
        if (params.type === "GET") {
            xhr.open(params.type, params.url + "?" + urlData, true);
            setHeaders(xhr, headers);
            xhr.send(null);
        } else {
            xhr.open(params.type, params.url, true);
            setHeaders(xhr, headers);
            xhr.send(JSON.stringify(params.data));
        }
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                var status = xhr.status;
                if (status >= 200 && status < 300) {
                    var response = "";
                    var type = xhr.getResponseHeader("Content-Type");
                    if (type.indexOf("xml") !== -1 && xhr.responseXML) { // xml格式
                        response = xhr.responseXML;
                    } else if (type.indexOf("application/json") !== -1) { // JSON格式
                        response = JSON.parse(xhr.responseText);
                    } else {
                        response = xhr.responseText; // 字符串格式
                    }
                    params.success && params.success(response);
                } else {
                    params.error && params.error(status);
                }
            }
        }
    }
    function jsonp(params) {
        var callbackName = params.jsonp; // 回调函数名
        var head = document.getElementsByTagName("head")[0];
        params.data["callback"] = callbackName;
        var data = formatParams(params.data);
        var script = document.createElement("script");
        head.appendChild(script);
        // 创建jsonp函数,成功后自动让success函数调用,在自动删除
        window[callbackName] = function (json) { // 设置回调,获取后台数据后才执行
            head.removeChild(script);
            clearTimeout(script.timer);
            window[callbackName] = null;
            params.success && params.success(json);
        };
        script.src = params.url + "?" + data; // 设置src的时候才开始向后台请求数据
        if (params.time) { // 限定时间
            script.timer = setTimeout(function () {
                window[callbackName] = null;
                head.removeChild(script);
                params.error && params.error({
                    message: "超时"
                })
            }, params.time)
        }

    }
    function formatParams(data) {
        // 使用 encodeURIComponent 对 URI的某部分编码
        var arr = [];
        for (var key in data) {
            arr.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
        }
        // 添加随机数,防止缓存
        arr.push("v=" + random());
        return arr.join("&");
    }
    function random() {
        return Math.floor(Math.random() * 10000 + 500);
    }
    function setHeaders(xhr, headers) {
        for (var key in headers) {
            xhr.setRequestHeader(key, headers[key]);
        }
    }
}
使用方法

不用jsonp请求

     Ajax({
    url: "后端接口",
    type: "POST",
    headers: {
      "Content-Type": "application/json",
      token: "xxx"
    },
    success(res) {
        console.log(res);
    },
    error(status) {
        console.log(`some error status = ${status}`);
    }
})

jsonp请求

  Ajax({
    url: "http://localhost:8080",
    headers: {
      "Content-Type": "application/json"
    },
    jsonp: "getUser",
    time: 2000,
    success(res) {
        console.log(res);
    },
    error(status) {
        console.log(`some error status = ${status.msg}`);
    }
})

jsonp后台配置代码
var querystring = require("querystring");
var http = require("http");
var server = http.createServer();

server.on("request", function(req, res) {
    var params = querystring.parse(req.url.split("?")[1]);
    var fn = params.callback;

    // jsonp返回设置
    res.writeHead(200, { "Content-Type": "text/javascript" });
    var data = {
        user: "xbc",
        password: "123456"
    }
    res.write(fn + "(" + JSON.stringify(data) + ")");

    res.end();
});

server.listen("8080");
console.log("Server is running at port 8080...");
参考文章

原生 JavaScript 实现 AJAX、JSONP

ajax 快速入门

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

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

相关文章

  • 前端相关大杂烩

    摘要:希望帮助更多的前端爱好者学习。前端开发者指南作者科迪林黎,由前端大师倾情赞助。翻译最佳实践译者张捷沪江前端开发工程师当你问起有关与时,老司机们首先就会告诉你其实是个没有网络请求功能的库。 前端基础面试题(JS部分) 前端基础面试题(JS部分) 学习 React.js 比你想象的要简单 原文地址:Learning React.js is easier than you think 原文作...

    fuyi501 评论0 收藏0
  • Jsonp及其实现原理

    摘要:同源策略,它是由提出的一个著名的安全策略,现在所有支持的浏览器都会使用这个策略。客户端在对文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像,但其实并不一样。 参考资料 一、先说说JSON 首先JSON是一种基于文本的数据交换方式,或者叫做数据描述格式。 JSON的优点: 基于纯文本,跨平台传递极其简单; Javas...

    TesterHome 评论0 收藏0
  • ajaxjsonp 不是一码事 细读详解

    摘要:只有两种数据类型描述符,大括号和方括号,其余英文冒号是映射符,英文逗号是分隔符,英文双引号是定义符。上述两种集合中若有多个子项,则通过英文逗号进行分隔。键值对以英文冒号进行分隔,并且建议键名都加上英文双引号,以便于不同语言的解析。 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现。当然了,通过调用强大的PhoneGap插件然后...

    张金宝 评论0 收藏0
  • ajaxjsonp 不是一码事 细读详解

    摘要:只有两种数据类型描述符,大括号和方括号,其余英文冒号是映射符,英文逗号是分隔符,英文双引号是定义符。上述两种集合中若有多个子项,则通过英文逗号进行分隔。键值对以英文冒号进行分隔,并且建议键名都加上英文双引号,以便于不同语言的解析。 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现。当然了,通过调用强大的PhoneGap插件然后...

    objc94 评论0 收藏0
  • Ajax详解

    摘要:当请求完成后注册一个回调函数。该请求是否触发全局处理事件如等,请求发送前的回调函数,用来修改请求发送前,此功能可用来设置自定义头信息,在函数中返回将取消这个请求。例如,为请求指定一个回调函数名。即改变回调函数的,默认就是传入的整个对象。 Ajax Ajax 全称是 asynchronous javascript and xml,并不是新的编程语言,可以说是已有技术的组合,主要用来实现客...

    jokester 评论0 收藏0

发表评论

0条评论

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