AJAX(Ci)

axios库

说明

  • 一种promise对象

1.使用步骤

  • 引入axios.js

  • 使用axios函数

  • 获取数据,并做后续处理

2.语法

<body>
    //引入axios.js
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> 
  <script>
      axios({请求配置项}).then(result=>{请求成功后运行}).catch(error =>{请求失败后运行})
  </script>
</body>

3.详解

请求配置项

  • 语法

    axios({
        请求配置项1,//逗号隔开
        请求配置项2
    })
  • 配置项类别

    • URL地址

      • 语法url:'目标资源地址'

    • 请求方法(不写默认GET)//不分大小写

      • 语法:method:'get'

      • 请求方法

        操作

        get

        获取数据

        post

        提交数据

        put

        修改数据(全部)

        delet

        删除数据

        patch

        修改数据(部分)

    • 查询参数

      • 作用:带参查询

      • 语法:params:{参数名1:值1,参数名2:值2}

    • 提交数据

      • 语法:data:{参数名:值}

    • 请求体

      • 语法:headers:{参数名:值}

.then

  • 语法.then(result =>{处理数据})

  • 获取数据

    • result.data 包含了服务器响应的内容//一个对象

    • result.data.属性名访问这个属性//eg:list

.catch

  • 语法.catch(error =>{处理错误})

  • 获取数据

    • error.response包含了服务器响应的内容//一个对象

4.错误处理

浏览器错误处理

axios错误处理

  • 查看:控制台-Uncaught (in promise)-response-data//错误信息

  • 获取:.catch(error =>{error.response})

  • 显示:弹窗提醒用户

5.图片上传

  • 语法

    • //绑定change事件
      document.querySelector('input').addEventListener('change',(e)={
         //获取图片文件对象
         console.log(e.target.files[0])
      //创建FormData对象
      const fd=new FormData()
      //使用FormData携带图片文件
      fd.append(参数名,值)
      //参数名:文档说明
      //值:图片文件
      //axios配置项中上传(文档指定位置)
      data:fd
      })

url

  • 概念:统一资源定位符,简称网址,用于访问网络上的资源

  • 资源分类

    • 网页资源

    • 图片资源

    • 数据资源

  • 组成

    • 协议

      • 指定传输格式

    • 域名(必需)

      • 服务器地址

    • 资源路径

      • 标记资源在服务器下的具体位置

  • 查询参数

    • 定义:带参查询

    • 语法:?参数名1=值1&参数名2=值2

      • 样例http://XXX.com/xxx/xxx?参数名1=值1&参数名2=值2

    • 实现:在axios里面用params实现

协议

HTTP协议

  • 说明:超文本传输协议,规定浏览器和服务器之间传输数据的格式

  • 请求报文

    • 定义:浏览器按照HTTP协议要求的格式,发送给服务器的内容

    • 组成:

      • 请求行

        • 请求方法

        • URL

        • 协议

      • 请求头

        • 以键值对的格式携带的附加信息

          • 比如:Content-Type(内容类型)

      • 请求体

        • 发送的资源

    • 查看

      • 开发者-网络-Fetch/XHR-操作对象-请求标头//请求头

      • 开发者-网络-Fetch/XHR-操作对象-负载//请求体

    • 错误排查

      • 说明:通过请求报文排查

  • 响应报文

    • 定义:服务器按照HTTP协议要求的格式,返回给浏览器的内容

    • 组成:

      • 响应行(状态行)

        • 协议

        • HTTP响应状态代码

        • 状态信息

      • 响应头

        • 以键值对的格式携带的附加信息

          • 比如:Content-Type(内容类型)

      • 空行

        • 分隔响应头和请求体

      • 请求体

        • 发送的资源

    • 查看

      • 开发者-网络-Fetch/XHR-操作对象-响应标头//响应行

      • 开发者-网络-Fetch/XHR-操作对象-响应//响应体

    • HTTP响应状态码

      • 定义:用来表明请求是否成功完成

      • 状态码

        说明

        1xx

        信息

        2xx

        成功

        3xx

        重定向消息

        4xx

        客户端错误

        5xx

        服务端错误

      • eg:404(服务器找不到资源)

https

接口文档

  • 接口文档

    • 描述接口的文章

  • 接口

    • 使用AJAX和服务器通讯时,使用的URL,请求方法,以及参数

  • 结构

    • url

    • 请求参数

      • 位置

        • head参数//请求头

          • 位置:axios配置项的headers:{}里面

        • body参数//请求体

          • 位置:axios配置项的data:{}里面

        • path路径传参

          • 位置:axios配置项的url改成模板字符串,规定位置写参数

        • query查询参数

          • 位置:axios配置项的params:{}里面

      • 格式

        • json//json字符串

        • form-data//表单数据对象

form-serialize插件

作用

  • 快速收集表单元素是的值

引入

  • 粘贴以下代码至单独js文件

  • script引入该文件

  • // get successful control from form and assemble into object
    // http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

    // types which indicate a submit action and are not successful controls
    // these will be ignored
    var k_r_submitter = /^(?:submit|button|image|reset|file)$/i;

    // node names which could be successful controls
    var k_r_success_contrls = /^(?:input|select|textarea|keygen)/i;

    // Matches bracket notation.
    var brackets = /(\[[^\[\]]*\])/g;

    // serializes form fields
    // @param form MUST be an HTMLForm element
    // @param options is an optional argument to configure the serialization. Default output
    // with no options specified is a url encoded string
    //   - hash: [true | false] Configure the output type. If true, the output will
    //   be a js object.
    //   - serializer: [function] Optional serializer function to override the default one.
    //   The function takes 3 arguments (result, key, value) and should return new result
    //   hash and url encoded str serializers are provided with this module
    //   - disabled: [true | false]. If true serialize disabled fields.
    //   - empty: [true | false]. If true serialize empty fields
    function serialize(form, options) {
       if (typeof options != 'object') {
           options = { hash: !!options };
      }
       else if (options.hash === undefined) {
           options.hash = true;
      }

       var result = (options.hash) ? {} : '';
       var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize);

       var elements = form && form.elements ? form.elements : [];

       //Object store each radio and set if it's empty or not
       var radio_store = Object.create(null);

       for (var i=0 ; i<elements.length ; ++i) {
           var element = elements[i];

           // ingore disabled fields
           if ((!options.disabled && element.disabled) || !element.name) {
               continue;
          }
           // ignore anyhting that is not considered a success field
           if (!k_r_success_contrls.test(element.nodeName) ||
               k_r_submitter.test(element.type)) {
               continue;
          }

           var key = element.name;
           var val = element.value;

           // we can't just use element.value for checkboxes cause some browsers lie to us
           // they say "on" for value when the box isn't checked
           if ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {
               val = undefined;
          }

           // If we want empty elements
           if (options.empty) {
               // for checkbox
               if (element.type === 'checkbox' && !element.checked) {
                   val = '';
              }

               // for radio
               if (element.type === 'radio') {
                   if (!radio_store[element.name] && !element.checked) {
                       radio_store[element.name] = false;
                  }
                   else if (element.checked) {
                       radio_store[element.name] = true;
                  }
              }

               // if options empty is true, continue only if its radio
               if (val undefined && element.type 'radio') {
                   continue;
              }
          }
           else {
               // value-less fields are ignored unless options.empty is true
               if (!val) {
                   continue;
              }
          }

           // multi select boxes
           if (element.type === 'select-multiple') {
               val = [];

               var selectOptions = element.options;
               var isSelectedOptions = false;
               for (var j=0 ; j<selectOptions.length ; ++j) {
                   var option = selectOptions[j];
                   var allowedEmpty = options.empty && !option.value;
                   var hasValue = (option.value || allowedEmpty);
                   if (option.selected && hasValue) {
                       isSelectedOptions = true;

                       // If using a hash serializer be sure to add the
                       // correct notation for an array in the multi-select
                       // context. Here the name attribute on the select element
                       // might be missing the trailing bracket pair. Both names
                       // "foo" and "foo[]" should be arrays.
                       if (options.hash && key.slice(key.length - 2) !== '[]') {
                           result = serializer(result, key + '[]', option.value);
                      }
                       else {
                           result = serializer(result, key, option.value);
                      }
                  }
              }

               // Serialize if no selected options and options.empty is true
               if (!isSelectedOptions && options.empty) {
                   result = serializer(result, key, '');
              }

               continue;
          }

           result = serializer(result, key, val);
      }

       // Check for all empty radio buttons and serialize them with key=""
       if (options.empty) {
           for (var key in radio_store) {
               if (!radio_store[key]) {
                   result = serializer(result, key, '');
              }
          }
      }

       return result;
    }

    function parse_keys(string) {
       var keys = [];
       var prefix = /^([^\[\]]*)/;
       var children = new RegExp(brackets);
       var match = prefix.exec(string);

       if (match[1]) {
           keys.push(match[1]);
      }

       while ((match = children.exec(string)) !== null) {
           keys.push(match[1]);
      }

       return keys;
    }

    function hash_assign(result, keys, value) {
       if (keys.length === 0) {
           result = value;
           return result;
      }

       var key = keys.shift();
       var between = key.match(/^\[(.+?)\]$/);

       if (key === '[]') {
           result = result || [];

           if (Array.isArray(result)) {
               result.push(hash_assign(null, keys, value));
          }
           else {
               // This might be the result of bad name attributes like "[][foo]",
               // in this case the original result object will already be
               // assigned to an object literal. Rather than coerce the object to
               // an array, or cause an exception the attribute "_values" is
               // assigned as an array.
               result._values = result._values || [];
               result._values.push(hash_assign(null, keys, value));
          }

           return result;
      }

       // Key is an attribute name and can be assigned directly.
       if (!between) {
           result[key] = hash_assign(result[key], keys, value);
      }
       else {
           var string = between[1];
           // +var converts the variable into a number
           // better than parseInt because it doesn't truncate away trailing
           // letters and actually fails if whole thing is not a number
           var index = +string;

           // If the characters between the brackets is not a number it is an
           // attribute name and can be assigned directly.
           if (isNaN(index)) {
               result = result || {};
               result[string] = hash_assign(result[string], keys, value);
          }
           else {
               result = result || [];
               result[index] = hash_assign(result[index], keys, value);
          }
      }

       return result;
    }

    // Object/hash encoding serializer.
    function hash_serializer(result, key, value) {
       var matches = key.match(brackets);

       // Has brackets? Use the recursive assignment function to walk the keys,
       // construct any missing objects in the result tree and make the assignment
       // at the end of the chain.
       if (matches) {
           var keys = parse_keys(key);
           hash_assign(result, keys, value);
      }
       else {
           // Non bracket notation can make assignments directly.
           var existing = result[key];

           // If the value has been assigned already (for instance when a radio and
           // a checkbox have the same name attribute) convert the previous value
           // into an array before pushing into it.
           //
           // NOTE: If this requirement were removed all hash creation and
           // assignment could go through hash_assign.
           if (existing) {
               if (!Array.isArray(existing)) {
                   result[key] = [ existing ];
              }

               result[key].push(value);
          }
           else {
               result[key] = value;
          }
      }

       return result;
    }

    // urlform encoding serializer
    function str_serialize(result, key, value) {
       // encode newlines as \r\n cause the html spec says so
       value = value.replace(/(\r)?\n/g, '\r\n');
       value = encodeURIComponent(value);

       // spaces should be '+' rather than '%20'.
       value = value.replace(/%20/g, '+');
       return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
    }

    //module.exports = serialize;

使用

  • 引入

  • 调用coanst data=serialize(表单对象,{hash:true,empty:true})

    • 返回:对象

      • {表单项name:value}

    • 参数

      • 参数1:表单对象

      • 参数2:配置对象

        • hash:设置获取数据结构

          • true//JS对象(推荐)

          • false//查询字符串

        • empty:是否获取空值

AJAX简介

  • 定义:浏览器与服务器进行数据通信的技术

AJAX作用

  • 发起HTTP请求

    • GET 请求:用于从服务器请求数据。

    • POST 请求:用于向服务器发送数据,通常用于创建资源。

    • PUT 请求:用于更新服务器上的资源。

    • DELETE 请求:用于从服务器删除资源。

AJAX原理

XMLHttpRequest

  • 语法

    //创建XMLHttpRequest对象
    const xhr = new XMLHttpRequest()
    //调用open方法,配置请求方法和url
    xhr.open('请求方法',url)
    //监听loadend事件,接受响应结果
    xhr.addEventListener('loadend', () => {
      console.log(xhr.response)
        xhr.status//本次请求的状态码
    })
    //发起请求
    chr.send()
  • 查询参数

    • 修改url

      • url后面+?参数名1=值&参数名2=值

      • 组织查询参数字符串

        •    const Obj={
                 参数1:值,
                 参数2:值
            }//查询参数对象
             const paramsObj=new URLSearchParams(Obj)
             //url使用模板字符串添加${paramsObj.toString()}

  • 数据提交

    • 语法

      •        
           const xhr = new XMLHttpRequest()
           
           xhr.open('请求方法',url)
           
           xhr.addEventListener('loadend', () => {
             console.log(xhr.response)
        })
               //请求头:设置content-Type:application/json
               xhr.setRequestHeader('content-Type','application/json')
               //请求体:携带JSON字符串
               const Obj{}//***数据填写位置
               const ObjStr=JSON.stringfy(ObjStr)
               //发送集体请求
               chr.send(ObjStr)

Promise对象

  • 作用

    • 表示一个异步操作的完成(或失败)及其结果

  • 状态

    • pending(进行中)

    • fulfilled(已成功)

    • rejected(已失败)

  • 语法

    • //1.创建Promise对象
      const Obj=new Promise((resolve,reject)=>{
         //2.执行异步任务,并传递结果
         setTimeout(()=>{
             resolve('传递成功结果')//二选一
             reject(new Error('传递失败结果'))//二选一
        },2000)
      })
      //参数1:resolve函数:设置promise状态为成功,触发then()执行
      //参数2:reject函数:promise状态为失败,触发catch()执行


      //3.接收结果
      Obj.then(result=>{
         //成功
      }).catch(error=>{
         //失败
         console.dir(error)//错误对象详细打印
      })

  • 链式调用

    • 步骤

      • 在本次then函数中返回一个新的promise对象

      • 新对象将在逻辑上以本次成功状态为前置条件

    • async,await

      • 定义:简便使用promise链式调用

      • 语法:

        • async function xxx(){}

          • 添加async关键字的函数将成为异步函数

        • await promise对象

          • 暂停函数代码执行

          • 直至promise对象完成,并获取其成功结果

      • 错误捕获

        • try{
             执行代码}catch(error){
                 //执行代码错误进入此处
                 console.dir(error)//错误的详细信息
            }

        • 说明

          • try里面的某行代码报错后,剩余代码不执行

  • all静态方法

    • 概念

      • 合并多个promise对象

      • 等待所有promise对象全部成功(或一个失败)

      • 做后续逻辑

    • 语法

      • const p=Promise.all([promise对象,promise对象])
        p.then(result=>{
              //结果数组的顺序与合并时的顺序一致
              }).catch(error=.{})

回调函数地狱

  • 概念

    • 多个回调函数嵌套

  • 缺点

    • 可读性差

    • 异常无法捕获

    • 耦合性严重

  • 解决方案

    • promise链式调用

请求拦截器

  • 说明

    • 发起请求之前,触发配置函数

    • 对请求参数进行额外配置

  • 语法

    • //添加请求拦截器
      axios.interceptors.request.use(function (config) {
       //在发送请求之前做什么
       
       return config
      }, function (error) {
       //请求错误做什么
       return Promise.reject(error)
      })

  • eg


    • axios.interceptors.request.use(function (config) {
       //获取token字符串
         const token = localStorage.getItem('token')
       //设置请求头
       token && ( config.headers.Authorization=`Bearer ${token}`)
       
       return config
      }, function (error) {
       return Promise.reject(error)
      })

响应拦截器

  • 说明

    • 响应回到then/catch之前,触发拦截器函数

    • 对响应结果统一处理

  • 语法

    • //添加响应拦截器
      axios.interceptors.response.use(function (response) {
       //在发送请求之前做什么
       
       return response
      }, function (error) {
       //请求错误做什么
         
       return Promise.reject(error)
      })

  • eg

    • ////添加响应拦截器
      axios.interceptors.response.use(function (response) {
       return response
      }, function (error) {
       //如果响应状态为401
       //清空本地存储
       //返回登录页面
       if (error?.response?.status === 401) {
         alert('登录状态已过期')
         localStorage.clear()
         location.href = '../login/index.html'
      }

       return Promise.reject(error)
      })


AJAX(Ci)
http://localhost:8090//archives/ajax-ci
作者
潘茜茜
发布于
2025年03月03日
许可协议