原生請求 js、jquery封裝的ajax請求、axios請求與fetch請求區別與優缺點


原生JS請求

現代瀏覽器,最開始與服務器交換數據,都是通過XMLHttpRequest對象。它可以使用JSON、XML、HTML和text文本等格式發送和接收數據。

首先我們先把原生的請求封裝一下:

xmlhttp=new XMLHttpRequest()
 function obj2str(data) {
        data = data || {}; // 如果沒有傳參, 為了添加隨機因⼦,必須⾃⼰創建⼀個對象
        data.t = new Date().getTime();
        var res = [];
        for (var key in data) {
            //在URL中是不可以出現中⽂的,如果出現了中⽂需要轉碼,可以調⽤encodeURIComponent⽅法,URL中
            res.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
        }
        return res.join("&");
    }

    function ajax(option) {
        var str = obj2str(option.data);//key=value&key=value;
        var xmlhttp, timer;
        if (option.type.toLowerCase() === "get") {//toLowerCase將⼤寫轉化為⼩寫
            xmlhttp.open(option.type, option.url + "?" + str, true)
            xmlhttp.send();
        } else {
            xmlhttp.open(option.type, option.url, true);
            //注意點:以下代碼必須放在open和send之間
            xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xmlhttp.send(str);
        }
        xmlhttp.onreadystatechange = function (ev2) {
            if (xmlhttp.readyState === 4) {
                clearInterval(timer);
                //判斷是否請求成功(Http狀態碼⼤於等於200,且⼩於300,和狀態碼等於304為請求成功)
                if (xmlhttp.status >= 200 && xmlhttp.status < 300 || xmlhttp.status === 304) {
                    option.success(xmlhttp);
                } else {
                    option.error(xmlhttp);
                }
            }
        };
        if (option.timeout) {
            timer = setInterval(function () {
                console.log("中斷請求");
                xmlhttp.abort();
                clearInterval(timer);
            }, option.timeout);
        }
    }

使用:

 ajax({
        url:"http://server-name/login",
        type:'post',
        data:{
            username:'username',
            password:'password'
        },
        dataType:'json',
        timeout:10000,
        contentType:"application/json",
        success:function(data){
      。。。。。。//服務器返回響應,根據響應結果,分析是否登錄成功
        },
        //異常處理
        error:function(e){
            console.log(e);
        }
    })

優點:

  1. 不重新加載頁面的情況下更新網頁
  2. 在頁面已加載后從服務器請求/接收數據
  3. 在后台向服務器發送數據。

缺點:

  1. 使用起來也比較繁瑣,需要設置很多值。
  2. 早期的IE瀏覽器有自己的實現,這樣需要寫兼容代碼。

Jq中的ajax:

為了更快捷的操作DOM,並且規避一些瀏覽器兼容問題,產生了jQuery。它里面的AJAX請求也兼容了各瀏覽器,可以有簡單易用的方法$.get$.post。簡單點說,就是對XMLHttpRequest對象的封裝。

$.ajax({
  type: 'POST',
  url: url, 
  data: data,
  dataType: dataType,
  success: function () {},
  error: function () {}
})

優點

  1. 對原生XHR的封裝,做了兼容處理,簡化了使用。
  2. 增加了對JSONP的支持,可以簡單處理部分跨域。

缺點

  1. 如果有多個請求,並且有依賴關系的話,容易形成回調地獄。
  2. 本身是針對MVC的編程,不符合現在前端MVVM的浪潮。
  3. ajax是jQuery中的一個方法。如果只是要使用ajax卻要引入整個jQuery非常的不合理。

Axios:

Axios是一個基於promiseHTTP庫,可以用在瀏覽器和 node.js 中。它本質也是對原生XMLHttpRequest的封裝,只不過它是Promise的實現版本,符合最新的ES規范。

axios({
    method: 'post',
    url: '/user/12345',
    data: {
      firstName: 'liu',
      lastName: 'weiqin'
    }
  })
  .then(res => console.log(res))
  .catch(err => console.log(err))

優點

  1. 從瀏覽器中創建XMLHttpRequests
  2. 從 node.js 創建 http 請求
  3. 支持 Promise API
  4. 攔截請求和響應
  5. 轉換請求數據和響應數據
  6. 取消請求
  7. 自動轉換 JSON 數據
  8. 客戶端支持防御 XSRF

缺點

  1. 只持現代代瀏覽器.

fetch:

Fetch API提供了一個 JavaScript 接口,用於訪問和操作HTTP管道的部分,例如請求和響應。它還提供了一個全局fetch()方法,該方法提供了一種簡單,合理的方式來跨網絡異步獲取資源。
fetch是低層次的API,代替XHR,可以輕松處理各種格式,非文本化格式。可以很容易的被其他技術使用,例如Service Workers。但是想要很好的使用fetch,需要做一些封裝處理。

fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

fetch目前遇到的問題

  1. fetch只對網絡請求報錯,對400500都當做成功的請求,需要封裝去處理
  2. fetch默認不會帶cookie,需要添加配置項。
  3. fetch不支持abort,不支持超時控制,使用setTimeoutPromise.reject的實現超時控制並不能阻止請求過程繼續在后台運行,造成了流量的浪費。
  4. fetch沒有辦法原生監測請求的進度,而XHR可以。
請注意,fetch規范與jQuery.ajax()主要有兩種方式的不同,牢記:

-. 當接收到一個代表錯誤的 HTTP 狀態碼時,從 fetch()返回的 Promise 不會被標記為 reject, 即使該 HTTP 響應的狀態碼是 404 或 500。相反,它會將 Promise 狀態標記為 resolve (但是會將 resolve的返回值的 ok 屬性設置為 false ),僅當網絡故障時或請求被阻止時,才會標記為 reject。

-. 默認情況下,fetch 不會從服務端發送或接收任何 cookies, 如果站點依賴於用戶 session,則會導致未經認證的請求(要發送 cookies,必須設置 credentials 選項)。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM