xhrからaxiosへのソースコード分析(1)

1.ajaxと一般的なhttpリクエストを区別します

まず、xhrを確認する必要があります。ページの最初の文を入力すると、XMLHttpRequest(XHR)オブジェクトを使用してサーバーと対話できます。ページ全体を更新しなくても、URLからデータを取得できます。これにより、Webページは、ユーザーの操作に影響を与えることなく、ページのコンテンツの一部を更新できます
    axiosを使用した後、リクエストの後にページが表示されるのは、クリックして更新する状況とは異なることは誰もが知っています。彼は、更新が必要なデータを自動的に更新し、それをページにエコーバックします。最下層はxhrです。
(1)Ajaxリクエストは特別なhttpリクエストです
(2)サーバーの場合、違いはありません、違いはブラウザ側にあります
(3)ブラウザは応答を受信します
       1)一般的なリクエスト:ブラウザは通常、応答の本文データを表示します、また、これは私たちがしばしばページの更新とジャンプと呼ぶものです
       2)Ajaxリクエスト:ブラウザはインターフェイスで操作を実行せず、リスナーコールバック関数を呼び出して応答データを渡すだけです。

2.XHRパッケージのシンプルなajax

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <button onclick="Get()">发送get请求</button>
  <button onclick="Post()">发送post请求</button>
  <button onclick="Delete()">发送delete请求</button>
  <button onclick="Put()">发送put请求</button>
</body>
<script>
  //查看network
      function Get(){
    
    
      axios({
    
    
        url:'xxx',
        method: 'GET',
        params:{
    
    
          id:1,
          hello:'xxx'
        }
      })
    }
    function Post(){
    
    
      axios({
    
    
        url:'xxx',
        method:'POST',
        data:{
    
    
          name:'张明',
          sex:'男'
        }
      })
    }
  //我们封装的函数需要具有以下几个特点(为什么要具有以下特点:我们需要实现一个axios的简单封装)
  // 1.函数的返回值为一个promise,成功的时候返回response,失败的时候返回error
  // 2.能够处理多种请求方式
  // 3.函数的参数为一个配置对象
    // {
    
    
    //   url:'',//请求地址
    //   method:'',//请求方式
    //   params:{},//get和delete携带的query参数
    //   data:{}//post和delete传参
    // }
  //4.响应json文件自动解析成js的对象或者数组
  function axios({
    
    
    url,//请求地址
    method='GET',//请求方式默认为get 当我们使用axios的时候如果我们不写method他会默认传递GET
    params={
    
    },//get和delete携带的query参数 默认空对象
    data={
    
    }//post和delete传参 默认空对象
  }){
    
    
    //返回一个promise对象
    return new Promise((resolve, reject)=>{
    
    
      //将method转大写
      method = method.toUpperCase();
      //处理query参数拼接到url
      let queryString = '';
      Object.keys(params).forEach(key => {
    
    
        queryString += `${
      
      key}=${
      
      params[key]}&`
      });
      //判断queryString最后的&
      if(queryString){
    
    
        queryString = queryString.substring(0,queryString.length-1)
        //拼接到url
        //说明本url指的是没有其他参数的url 如果已经拼接过不能用这种方法
        url += '?'+queryString
      }
      //执行异步请求
      //(1)创建XHR对象
      const request = new XMLHttpRequest();
      //(2)创建连接(初始化请求)
      request.open(method,url)
      //(3)发送请求
      if(method == 'GET'  || method == 'DELETE'){
    
    
        request.send()
      }else if(method == 'POST' || method == 'PUT'){
    
    
        //告诉服务器请求体的格式是json
        request.setRequestHeader('Content-Type','application/json;charset=utf-8');
        request.send(JSON.stringify(data));
      }

      //绑定状态改变的监听
      //说明为什么监听函数可以绑定在send后面(因为send()请求是异步的,不是同步的,所以不影响监听)
      request.onreadystatechange = function(){
    
    
        //如果请求没有完成,直接结束
        if(request.readyState !== 4){
    
    
          return;
        }
        //响应状态码[200,299]代表成功
        const {
    
    status, statusText} = request;
        //如果请求成功调用resolve()
        if(status>=200 && status<=299){
    
    
          const response={
    
    
            data:JSON.parse(request.response),
            status,
            statusText
          }
          resolve(response);
        }else{
    
    
          reject(new Error('request error status is'+status))
        }
        //如果请求失败调用reject()
      }
      
    })
  }
</script>
</html>

おすすめ

転載: blog.csdn.net/lbchenxy/article/details/105365531