美文网首页
26.1、同步/异步请求、混编、Ajax、封装Ajax

26.1、同步/异步请求、混编、Ajax、封装Ajax

作者: 一土二月鸟 | 来源:发表于2020-07-13 07:24 被阅读0次
    • 同步、异步请求
      • 点击一个超链接、打开一个网站都属于同步请求
      • JSP、ASP大多数情况属于混编模式,通过事件触发http请求,服务器根据请求的参数,重新组装页面,然后将页面返回给浏览器。这种属于混编+同步请求,

    Ajax

    • ajax全称:Async javascript and xml表示异步的js和xml
    • readyState代表http请求处于哪个阶段
    • status代表http状态码
            function xhrequest (url) {
                let xhr = null;
    
                if (XMLHttpRequest) { // 使用XMLHttpRequest实例化对象可以操作ajax
                    xhr = new XMLHttpRequest();
                } else { // ie5 ie6 需要使用ActiveXObject
                    xhr = new ActiveXObejct("Microsoft.XMLHTTP");
                }
    
                console.log(xhr.readyState); // 0 代表xhr未初始化
                xhr.open('get', url, true); // true代表异步的方式,false代表同步
                console.log(xhr.readyState); // 1 代表http连接已建立
                xhr.send(); // 如果是post请求,send里需要写"a=1&b=2"格式的字符串参数,此方式为传统的post表单格式,更多类型见1-1例。 
    
                xhr.onreadystatechange = () => {
                    console.log(xhr.readyState); // 2 代表请求已接受 3 代表请求处理中 4代表请求已处理完毕
                    console.log(xhr.status);
                    if(xhr.status == 200 && xhr.readyState == 4){
                        console.log(xhr.responseText);
                    }
                }
    
            }
    
            xhrequest('http://www.webqd.top:8080');
    
    • extends 1-1
          function send(type) {
                url = "http://127.0.0.1:8080/";
                xhr = new XMLHttpRequest();
                xhr.open("post", url, true);
                var data;
                if (type === "formdata") {
                    data = new FormData();
                    data.append("key", "value");
                } else if (type === "json") {
                    xhr.setRequestHeader("Content-Type", "application/json");
                    data = JSON.stringify({"key": "value"});
                } else if (type === "text") {
                    data = "key=value";
                } else if (type === "www") {
                    // 这个header 其实是 传统post 表单的格式
                    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                    data = "key=value";
                }
                xhr.send(data);
            }
    

    封装ajax

    var $ = function (w) {
    
      function formatData (data) {
        if(!data) return null;
    
        var str = '',
            toStr = Object.prototype.toString;
    
        for( var key in data ) {
          if ( toStr.call(data[key]) === '[object Object]' 
            || toStr.call(data[key]) === '[object Array]' ) {
              // 待实现
          }
          str += key + '=' + data[key] + '&';
        }
        str = str.replace(/&$/, '');
        return str;
      }
    
      function _doAjax(opt) {
        var xhr = null;
        if (w.XMLHttpRequest) {
          xhr = new XMLHttpRequest();
        } else {
          xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
    
        opt = opt || {};
    
        if (!opt.url) throw new Error("url为必填项");
    
        let url = opt.url,
          type = (opt.type || 'GET').toUpperCase(),
          data = opt.data || null,
          contentType = opt.contentType || 'application/x-www-form-urlencoded', // 只有post请求时,需要设置请求的数据类型
          dataType = (opt.dataType || 'json').toLowerCase(), // 服务器返回的数据类型
          async = (opt.async + '') === 'false' ? false : true,
          timeout = opt.timeout || 30000, // 如果设置0,默认为30秒 todo:封装其他类型  回调等 
          success = opt.success || function () {},
          error = opt.error || function () {},
          complete = opt.complete || function () {},
          tId = null;
    
    
        xhr.onreadystatechange = function () { // 此函数必须在send方法执行前进行定义,否则无法实现同步
          if (xhr.readyState === 4) {
    
            if (xhr.status === 304 || (xhr.status >= 200 && xhr.status < 300)) {
    
              switch (dataType) {
                case 'json': 
                  success(JSON.parse(xhr.responseText));
                  break;
                case 'text':
                  success(xhr.responseText);
                  break;
                case 'xml':
                case 'html':
                  success(xhr.responseXml);
                  break;
                default :
                  success(xhr.responseText); 
              }
    
            } else {
              error(xhr.statusText);
            }
    
            clearTimeout(tId);
            tId = null;
            xhr = null;
            complete("The request of " + url + " has completed");
    
          }
        }
    
        tId = setTimeout(function () {
          clearTimeout(tId);
          xhr.abort(); // 终止已发出的请求
          tId = null;
          xhr = null;
          throw new Error('The request has time out');
        }, timeout);
    
        xhr.open(type, url, async);
        if (type === 'POST') xhr.setRequestHeader('Content-Type', contentType);
        // xhr.setResponseType = dataType;  // TOOD: 待优化,将xml html转为document 设置blob、arrayBuffer、ms-stream、"" 类型
        xhr.send(formatData(data)); // 如果是同步,send方法会等待readyState为4的时候才会继续执行后面的代码
      }
    
      return {
        ajax: function (options) {
          _doAjax(options);
        },
        post: function (url, data, cb) {
          this.ajax({
            url: url,
            type: 'post',
            data: data,
            success: cb,
          });
        },
        get: function (url, cb) {
          this.ajax({
            url: url,
            success: cb,
          });
        }
      };
    }(window);
    

    相关文章

      网友评论

          本文标题:26.1、同步/异步请求、混编、Ajax、封装Ajax

          本文链接:https://www.haomeiwen.com/subject/hwmocktx.html