js XMLHttpRequest請求數據+簡單封裝【前端基礎篇(一)】

前端基礎篇(一):XMLHttpRequest封裝$.ajax()

XMLHttpRequest

XMLHttpRequest(XHR)對象用于與服務器交互。通過 XMLHttpRequest 可以在不刷新頁面的情況下請求特定 URL,獲取數據。這允許網頁在不影響用戶操作的情況下,更新頁面的局部內容。XMLHttpRequest 在 AJAX 編程中被大量使用。
XMLHttpRequest

本期任務

  • 使用XHR訪問本地文件
  • 使用XHR訪問網絡資源
  • 簡易封裝成$.ajax()

準備工作

  • 安裝nodejs中文網下載直接安裝
  • 打開cmd運行npm install http-server -g安裝http服務工具
  • 創建文件夾->index.html、data.txt、data.json
  • 在文件夾中cmd運行http-server 訪問:http://127.0.0.1:8080

開始工作

  • XHR請求本地文件

    • 請求data.txt文件

      <script type="text/javascript">
          var xhr = new XMLHttpRequest();
          xhr.onreadystatechange = function () {
              if (xhr.readyState === 4) {
                  document.body.innerText = xhr.responseText
              }
          }
          xhr.open('get', 'data.txt')
          xhr.send();
      </script>
      

      頁面顯示

      這是我的文本數據

      xhr.readyState === 4表示下載操作已完成。

      image.png

  • 請求data.json文件
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
          var data = JSON.parse(xhr.response)
          document.body.innerText = data.msg
      }
  }
  xhr.open('get', 'data.json')
  xhr.send();
頁面顯示
> 這是我的json數據
  • 請求圖片

      var xhr = new XMLHttpRequest();
      xhr.responseType = "blob";
      xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
              // 將文件轉化為可訪問地址
              var url = URL.createObjectURL(xhr.response)
              // 創建圖片節點,將可訪問地址賦值給img.src
              var img = document.createElement('img')
              img.src = url
              // 向頁面追加元素
              document.body.appendChild(img)
          }
      }
      xhr.open('get', './imgs/05.png')
      xhr.send();
    

    <font color=#fa8c16>挖的坑:</font>事先不知道前端可以主動指定responseType,獲取出來的響應內容,一直亂碼,后查詢mdn發現該屬性可以自己手動設置,只要在open、send方法之前設置即可,地址放這里了:XMLHttpRequest.responseType

  • 網絡請求(調用webapi)

    在實際應用中我們不僅僅是要調用本地的資源,更多的時候我們需要調用互聯網資源(api),示例中使用的是webapi。項目地址為.net 5 webapi

    • get
      • 不帶參數

        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                // 向頁面追加元素
                document.body.innerText = xhr.response
            }
        }
        xhr.open('get', 'http://localhost:5000/api/Values')
        xhr.send();
        

        請求結果報錯了


        image.png

        這是我們網絡請求常見的錯誤<font color=#d48806>跨域</font>這是瀏覽器為了安全不允許訪問跨域的資源,一般服務端進行跨域設置即可。
        修改后端跨域后,添加斷點請求結果如下:


        image.png
      • 帶參數

        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                // 向頁面追加元素
                document.body.innerText = xhr.response
            }
        }
        xhr.open('get', 'http://localhost:5000/api/Values/user?id=1') // 帶參數
        xhr.send();
        
    • post-帶復雜參數
        var data = { name: '里斯', age: 32, address: '四川南充' }
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                // 向頁面追加元素
                debugger
                document.body.innerText = xhr.response
            }
        }
        xhr.open('post', 'http://localhost:5000/api/Values') // 帶參數
        xhr.setRequestHeader('content-type', 'application/json')// 設置服務端要求的參數類型,后面會專門出一期,針對各種常用content-type講解
        xhr.send(JSON.stringify(data));// 帶上復雜參數
      

      post請求時,復雜參數需要指定請求類型content-type,具體類型根據服務端要求

  • 封裝$.ajax

    上面講解了XHR基本請求方式,下面我們對常用的一些操作進行封裝,對于接觸過JQuery的盆友來說,會很熟悉

    代碼

    var $ = (function () {
    // 定義一些允許外界修改的值
    const propertys = [
        "abort",
        "error",
        "load",
        "loadend",
        "loadstart",
        "progress",
        "timeout",
        "success",
        "type",
        "async",
        "url",
        "data",
        "params",
        "contentType",
    ];
    /**
    *
    * @description 請求的核心方法-原生
    * @param {*} [options={}]
    */
    function xhrHandle(options = {}) {
        const type = options.type || "get"; // 設置請求類型,如果沒有傳請求類型,默認為get
        const async = options.async || true; // 是否時異步請求,默認為true,如果是同步請求,頁面會在請求數據時假死
        var url = options.url || location.origin; // 如果沒有傳請求地址,那就默認當前源為目標地址
        var contentType =
        options.contentType || "application/x-www-form-urlencoded"; // 設置默認的請求類型
        var data = undefined; // data為post發送數據
        if (options.contentType.indexOf("json") > -1 && options.data)
        // 當花括號內容只有一行時,可以省略
        data = JSON.stringify(options.data);
        // 將對象轉換為json字符串發送給后臺
        else data = buildParams(options.data);
        if (options.params)
        // 構建url參數或者表單數據
        url += "?" + buildParams(options.params);
        // 實例化xhr對象
        var xhr = new XMLHttpRequest();
        // 遍歷并快速賦值到我們xhr對象上,好處是不用一個一個賦值,壞處,需要控制好屬性,不必要的屬性也會添加到對象上
        for (var key of propertys) {
        xhr[key] = options[key];
        }
        // 在xhr狀態發生改變時進行我們success方法的業務執行
        xhr.onreadystatechange = function () {
        // readyState:4 表示資源下載完成
        // status:200 表示服務器返回正確
        if (xhr.readyState === 4 && xhr.status === 200)
            options.success && options.success(xhr.response); // 判斷是否有success方法并執行
        };
        // 配置請求類型和目的地址
        xhr.open(type, url, async);
        // 設置請求頭
        xhr.setRequestHeader("content-type", contentType);
        // 發送數據到服務端
        xhr.send(data);
    }
    
    /**
    *
    * @description 構建params參數
    * @param {*} obj
    * @return {*}
    */
    function buildParams(obj) {
        var vs = [];
        for (var key in obj) {
        vs.push(key + "=" + obj[key]);
        }
        return vs.join("&"); // 通過  &  符號合并數組的字段
    }
    
    return {
        /** ajax請求 */
        ajax: xhrHandle,
        /** post請求 */
        post: (url, data, success, contentType) => {
        xhrHandle({ type: "post", url, data, success, contentType });
        },
        /** get請求 */
        get: (url, params, success) => {
        xhrHandle({ type: "get", url, params, success });
        },
    };
    })();
    

    用法

    <script type="text/javascript" src="ajax.js?v=1.16"></script>引入文件

    <!-- 使用封裝的ajax方法請求 -->
    <script type="text/javascript">
        var data = {
            name: '張三',
            age: 23,
            address: '來自天堂'
        }
        var success = function (data) {
            var p = document.createElement('p')
            p.innerText = data;
            document.body.appendChild(p)
        }
        // 不帶參數get請求
        $.ajax({
            url: 'http://localhost:5000/api/Values',
            type: 'get',
            success
        })
        $.get('http://localhost:5000/api/Values', {}, success)
        // 帶參數get請求
        $.ajax({
            url: 'http://localhost:5000/api/Values/user',
            params: { id: 1 },
            success
        })
        $.get('http://localhost:5000/api/Values/user', { id: 1 }, success)
    
        // post請求
        $.ajax({
            type: 'post',
            url: 'http://localhost:5000/api/Values',
            contentType: 'application/json',
            data,
            success: function (data) {
                alert(data)
            }
        })
        $.post('http://localhost:5000/api/Values', data, function (data) {
            alert('這是$.post' + data)
        }, 'application/json')
    </script>
    

XHR屬性說明

  • MDN:XMLHttpRequest

  • 我們通常使用onreadystatechange事件、State狀態

  • 運行打印xhr包含的常用屬性console.log(xhr);

    image.png

  • 簡單介紹各個屬性


    image.png
    image.png

寫在后面

本節內容打算分兩期的,但是感覺沒必要,基礎的知識比較多,想到什么寫什么,所以比較亂,如果你看到這里了,不妨點個贊,歡迎評論區見。本期項目地址1.js XMLHttpRequest請求數據+簡單封裝

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容