zoukankan      html  css  js  c++  java
  • JavaScript XmlHttpRequest

    XmlHttpRequest

       这是原生的一种发送网络请求的技术,存在非常久的方案。

       基本上所有框架对于网络请求的部分都是基于它来做的。

    方法介绍

    open

       open()用于创建请求(单纯创建,并不发送)

       注意:如果是open()methodGET,则需要自带参数。

    参数说明
    method 请求方式
    url 请求地址
    async 是否异步

    send

       send()用于发送请求,如果你的open()methodGET,则这里可以填上null

    参数说明
    body 要发送的数据(字符串类型)
    function ajax() {
        let xhr = new XMLHttpRequest();
        xhr.open("GET", "http://127.0.0.1:8000/", true);
        xhr.send(null);
    
    }
    

    setRequestHeader

       用于设置请求头,一般我们会指定编码方式。

    参数说明
    header 请求头的key(字符串类型)
    vlaue 请求头的value(字符串类型)

    getAllResponseHeaders

       用于获取响应头,返回所有的响应头数据(字符串类型)。

    getResponseHeader

       获取响应头中指定header的值,返回该响应头的数据(字符串类型)。

      

    参数描述
    header 响应头的key(字符串类型)

    abort

       终止请求。

    属性介绍

    status

       状态码,如200/404等等。

    readyState

       这是一个整数类型的状态值,使用XmlHttpRequest时共有5种状态。

    状态值描述
    0 未初始化,尚未调用open()方法
    1 启动,调用了open()方法,未调用send()方法
    2 发送,已经调用了send()方法,未接收到响应
    3 接收,已经接收到部分响应数据
    4 完成,已经接收到全部响应数据

    statesText

       状态文本(字符串),如:OK、NotFound...

    responseText

       这是服务器返回的数据(字符串类型)

    XmlDocument

       XmlDocumentresponseXML一样,都是 服务器返回的数据(Xml对象)

    回调函数

    onreadystatechange

       当readyState的值改变时自动触发执行其对应的函数(回调函数)

       有了这个回调函数,我们就可以开始做一个原生的ajax了。

    使用方式

    简单封装

       这下面是一个最简单的封装。

        function ajax() {
    
            let xhr = new XMLHttpRequest();
            xhr.open("GET", "http://127.0.0.1:8000/?username=Yunya", true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            xhr.send(null);
            // 如果是POST请求,则 数据格式为 xhr.send('n1=1;n2=2;');
    
    
            xhr.onreadystatechange = function(){
                console.log(xhr.status);
                if (xhr.readyState == 4 && xhr.status==200){
                    console.log("请求成功");
                    console.log(xhr.responseText);
                }
                else if(xhr.status == 404){
                    console.log("请求失败");
                }
                else if(xhr.status == 500){
                    console.log("服务器内部错误")
                }
            }
        }
    

    初级封装

       下面是融合了POSTGET的封装,基本使用与jQueryajax相同

    (function () {
    
        class Ajax {
    
            constructor({ url, type, dataType, data, contentType, success, error }) {
                this.url = url;
                this.type = type;
                this.data = data;
                this.contentType = !!contentType == true ? contentType : 'application/x-www-form-urlencoded';
                this.success = typeof success == "function" ? success : (res) => { };
                this.error = typeof error == "function" ? error : (res) => { };
                this.xhr = null;
                this.send_data = null;
                this.init();
            }
    
            init() {
                // 第一步,处理上传的数据格式
                this.dataFormat();
                // 第二步:如果是GET提交,则send()中不能有任何数据
                if (this.type == "GET") {
                    this.getAjax();
                } else if (this.type == "POST") {
                    this.postAjax();
                }
                // 第三步:判断后端返回信息
                this.callbackAjax();
            }
    
            dataFormat() {
                this.send_data = Object.entries(this.data).reduce((prev, value, index, array) => {
                    if (array.length - 1 == index) {
                        return prev += `${value[0]}=${value[1]}`
                    }
                    else {
                        return prev += `${value[0]}=${value[1]}&`
                    }
    
                }, "")
    
            }
    
            getAjax() {
                this.url = this.url.concat('?', this.send_data,);
                this.xhr = new XMLHttpRequest();
                this.xhr.open(this.type, this.url, true);
                this.xhr.setRequestHeader("Content-Type", this.contentType)
                this.xhr.send(null);
    
    
            }
    
            postAjax() {
                this.xhr = new XMLHttpRequest();
                this.xhr.open(this.type, this.url, true);
                this.xhr.setRequestHeader("Content-Type", this.contentType)
                this.xhr.send(this.send_data);
    
            }
    
    
            callbackAjax() {
                this.xhr.onreadystatechange = () => {
                    if (this.xhr.readyState == 4 && this.xhr.status == 200) {
                        if (this.dataType == "JSON") {
                            this.success(JSON.parse(this.xhr.responseText));
                        } else {
                            this.success(this.xhr.responseText);
                        }
    
                    } else if (this.xhr.status == 404) {
                        this.error("请求失败,检查IP与PORT");
                    } else if (this.xhr.status == 500) {
                        this.error("请求失败,服务器内部错误");
                    }
                }
    
            }
    
    
        }
        window.Ajax = Ajax;
    }())
    
    // 调用方式 new Ajax() 传入参数即可
    

    文件上传

       由于上面不支持文件上传,所以我们需要再做一个有文件上传功能的AJAX

    (function () {
    
        class Ajax {
    
            constructor({ url, type, dataType, data, contentType, success, error,file=false }) {
                this.url = url;
                this.type = type;
                this.data = data;
                this.contentType = !!contentType == true ? contentType : 'application/x-www-form-urlencoded';
                this.success = typeof success == "function" ? success : (res) => { };
                this.error = typeof error == "function" ? error : (res) => { };
                this.xhr = null;
                this.send_data = null;
                this.file = file; // 是否支持文件上传
                this.init();
            }
    
            init() {
                // 第一步,处理上传的数据格式
    
                this.dataFormat();
    
                // 第二步:如果是GET提交,则send()中不能有任何数据
                if (this.type == "GET") {
                    this.getAjax();
                }else if (this.file){
                    this.fileAjax();
                }
                else if (this.type == "POST") {
                    this.postAjax();
                }
                // 第三步:判断后端返回信息
                this.callbackAjax();
            }
    
            dataFormat() {
                this.send_data = Object.entries(this.data).reduce((prev, value, index, array) => {
                    if (array.length - 1 == index) {
                        return prev += `${value[0]}=${value[1]}`
                    }
                    else {
                        return prev += `${value[0]}=${value[1]}&`
                    }
    
                }, "")
    
            }
    
            getAjax() {
                this.url = this.url.concat('?', this.send_data,);
                this.xhr = new XMLHttpRequest();
                this.xhr.open(this.type, this.url, true);
                this.xhr.setRequestHeader("Content-Type", this.contentType);
                this.xhr.send(null);
    
    
            }
    
            postAjax() {
                this.xhr = new XMLHttpRequest();
                this.xhr.open(this.type, this.url, true);
                this.xhr.setRequestHeader("Content-Type", this.contentType);
                this.xhr.send(this.send_data);
    
            }
    
            fileAjax(){
                // 注意,文件上传只能是POST形式
                this.xhr = new XMLHttpRequest();
                this.xhr.open("POST", this.url,true);
                this.xhr.send(this.data);  // 注意,这里是上传的this.data
            }
    
    
            callbackAjax() {
                this.xhr.onreadystatechange = () => {
                    if (this.xhr.readyState == 4 && this.xhr.status == 200) {
                        if (this.dataType == "JSON") {
                            this.success(JSON.parse(this.xhr.responseText));
                        } else {
                            this.success(this.xhr.responseText);
                        }
    
                    } else if (this.xhr.status == 404) {
                        this.error("请求失败,检查IP与PORT");
                    } else if (this.xhr.status == 500) {
                        this.error("请求失败,服务器内部错误");
                    }
                }
    
            }
    
    
        }
        window.Ajax = Ajax;
    }())
    

    json格式

       如果需要发送JSON格式的数据,则我们还需要进行改进。

       首先要明确,GET提交方式不要使用JSON格式的数据进行发送。

       如果你后端是使用Django的话,那么json格式不会存放进request.POST中,而是存放request.body中。

       说明:filetrue时,代表上传文件,json_datatrue时,代表前端发送json数据至后端,dataTypeJSON时,代表自动转换后端传过来的json格式数据。

    (function () {
    
        class Ajax {
    
            constructor({ url, type, dataType, data, contentType, success, error,file=false,json_data=false }) {
                this.url = url;
                this.type = type;
                this.data = data;
                this.contentType = !!contentType == true ? contentType : 'application/x-www-form-urlencoded';
                this.success = typeof success == "function" ? success : (res) => { };
                this.error = typeof error == "function" ? error : (res) => { };
                this.xhr = null;
                this.send_data = null;
                this.file = file; // 是否支持文件上传
                this.json_data = json_data;
                this.init();
            }
    
            init() {
    
                // 如果是GET+JSON格式发送则抛出异常
    
                if(this.json_data && this.type=='GET'){
                    throw new Error("不可使用GET方式提交JSON数据");
                }else if(this.json_data && this.file ){
                    throw new Error("提交文件不可使用JSON数据");
    
                }
    
                // 第一步,处理上传的数据格式
                if(!this.json_data){
                    this.dataFormat();
                }
                else{
                    this.dataJson();
                }
    
                // 第二步:如果是GET提交,则send()中不能有任何数据
                if (this.type == "GET") {
                    this.getAjax();
                }else if (this.file){
                    this.fileAjax();
                }
                else if (this.type == "POST") {
                    this.postAjax();
                }
                // 第三步:判断后端返回信息
                this.callbackAjax();
            }
    
            dataFormat() {
                this.send_data = Object.entries(this.data).reduce((prev, value, index, array) => {
                    if (array.length - 1 == index) {
                        return prev += `${value[0]}=${value[1]}`
                    }
                    else {
                        return prev += `${value[0]}=${value[1]}&`
                    }
    
                }, "")
    
            }
    
            dataJson(){
                this.send_data = JSON.stringify(this.data);
            }
    
            getAjax() {
                this.url = this.url.concat('?', this.send_data,);
                this.xhr = new XMLHttpRequest();
                this.xhr.open(this.type, this.url, true);
                this.xhr.setRequestHeader("Content-Type", this.contentType);
                this.xhr.send(null);
    
    
            }
    
            postAjax() {
                this.xhr = new XMLHttpRequest();
                this.xhr.open(this.type, this.url, true);
                // 判断是否发送JSON数据格式
                if (this.json_data){
                    this.xhr.setRequestHeader("HTTP_X_REQUESTED_WITH","XMLHttpRequest");
                    this.xhr.setRequestHeader("Content-Type","application/json");
                }else{
                    this.xhr.setRequestHeader("Content-Type", this.contentType);
                }
                this.xhr.send(this.send_data);
    
            }
    
            fileAjax(){
                // 注意,文件上传只能是POST形式
                this.xhr = new XMLHttpRequest();
                this.xhr.open("POST", this.url,true);
                this.xhr.send(this.data);  // 注意,这里是上传的this.data
            }
    
    
            callbackAjax() {
                this.xhr.onreadystatechange = () => {
                    if (this.xhr.readyState == 4 && this.xhr.status == 200) {
                        if (this.dataType == "JSON") {
                            this.success(JSON.parse(this.xhr.responseText));
                        } else {
                            this.success(this.xhr.responseText);
                        }
    
                    } else if (this.xhr.status == 404) {
                        this.error("请求失败,检查IP与PORT");
                    } else if (this.xhr.status == 500) {
                        this.error("请求失败,服务器内部错误");
                    }
                }
    
            }
    
    
        }
        window.Ajax = Ajax;
    
    }())
    
  • 相关阅读:
    带你进入异步Django+Vue的世界
    xps转换为pdf
    当对函数的返回值有多种需求时(执行是否成功,及业务数据的返回值),可采用的方法
    WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)
    集群、限流、缓存 BAT 大厂无非也就是这么做
    C#简单爬取数据(.NET使用HTML解析器ESoup和正则两种方式匹配数据)
    公共静态函数、属性 的 “关联成员” 的 生命周期
    python 之 Django框架(ORM常用字段和字段参数、关系字段和和字段参数)
    Django文档
    go micro 微服务框架温习
  • 原文地址:https://www.cnblogs.com/Yunya-Cnblogs/p/13674334.html
Copyright © 2011-2022 走看看