成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

分別使用 XHR、jQuery 和 Fetch 實(shí)現(xiàn) AJAX

Julylovin / 872人閱讀

摘要:本文詳細(xì)講述如何使用原生和來實(shí)現(xiàn)。使用可以無刷新地向服務(wù)端發(fā)送請求接收服務(wù)端響應(yīng),并更新頁面。分別要用到的方法和方法。,,都是現(xiàn)在和未來解決異步的標(biāo)準(zhǔn)做法,可以完美搭配使用。這也是使用標(biāo)準(zhǔn)一大好處。

本文詳細(xì)講述如何使用原生 JS、jQuery 和 Fetch 來實(shí)現(xiàn) AJAX。

AJAX 即 Asynchronous JavaScript and XML,異步的 JavaScript 和 XML。使用 AJAX 可以無刷新地向服務(wù)端發(fā)送請求接收服務(wù)端響應(yīng),并更新頁面。

一、原生 JS 實(shí)現(xiàn) AJAX

JS 實(shí)現(xiàn) AJAX 主要基于瀏覽器提供的 XMLHttpRequest(XHR)類,所有現(xiàn)代瀏覽器(IE7+、Firefox、Chrome、Safari 以及 Opera)均內(nèi)建 XMLHttpRequest 對象。

1. 獲取XMLHttpRequest對象
// 獲取XMLHttpRequest對象
var xhr = new XMLHttpRequest();

如果需要兼容老版本的 IE (IE5, IE6) 瀏覽器,則可以使用 ActiveX 對象:

var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
  xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
  try {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
  }
}
2. 發(fā)送一個 HTTP 請求

接下來,我們需要打開一個URL,然后發(fā)送這個請求。分別要用到 XMLHttpRequest 的 open() 方法和 send() 方法。

// GET
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
  xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
  try {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
  }
}
if (xhr) {
  xhr.open("GET", "/api?username=admin&password=root", true);
  xhr.send(null);
}
// POST
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
  xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
  try {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
  }
}
if (xhr) {
  xhr.open("POST", "/api", true);
  // 設(shè)置 Content-Type 為 application/x-www-form-urlencoded
  // 以表單的形式傳遞數(shù)據(jù)
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  xhr.send("username=admin&password=root");
}

open() 方法有三個參數(shù):

open() 的第一個參數(shù)是 HTTP 請求方式 – GET,POST,HEAD 或任何服務(wù)器所支持的您想調(diào)用的方式。按照HTTP規(guī)范,該參數(shù)要大寫;否則,某些瀏覽器(如Firefox)可能無法處理請求。有關(guān)HTTP請求方法的詳細(xì)信息可參考 https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

第二個參數(shù)是請求頁面的 URL。由于同源策略(Same origin policy)該頁面不能為第三方域名的頁面。同時一定要保證在所有的頁面中都使用準(zhǔn)確的域名,否則調(diào)用 open() 會得到 permission denied 的錯誤提示。

第三個參數(shù)設(shè)置請求是否為異步模式。如果是 TRUE,JavaScript 函數(shù)將繼續(xù)執(zhí)行,而不等待服務(wù)器響應(yīng)。這就是 AJAX 中的 A。

如果第一個參數(shù)是 GET,則可以直接將參數(shù)放在 url 后面,如:http://nodejh.com/api?name=admint&password=root

如果第一個參數(shù)是 POST,則需要將參數(shù)寫在 send() 方法里面。send() 方法的參數(shù)可以是任何想送給服務(wù)器的數(shù)據(jù)。這時數(shù)據(jù)要以字符串的形式送給服務(wù)器,如:name=admint&password=root。或者也可以傳遞 JSON 格式的數(shù)據(jù):

// 設(shè)置 Content-Type 為 application/json
xhr.setRequestHeader("Content-Type", "application/json");
// 傳遞 JSON 字符串
xhr.send(JSON.stringify({ username:"admin", password:"root" }));

如果不設(shè)置請求頭,原生 AJAX 會默認(rèn)使用 Content-Type 是 text/plain;charset=UTF-8 的方式發(fā)送數(shù)據(jù)。

關(guān)于 Content-Type 更詳細(xì)的內(nèi)容,將在以后的文章中解釋說明。

3. 處理服務(wù)器的響應(yīng)

當(dāng)發(fā)送請求時,我們需要指定如何處理服務(wù)器的響應(yīng),我們需要用到 onreadystatechange 屬性來檢測服務(wù)器的響應(yīng)狀態(tài)。使用 onreadystatechange 有兩種方式,一是直接 onreadystatechange 屬性指定一個可調(diào)用的函數(shù)名,二是使用一個匿名函數(shù):

// 方法一 指定可調(diào)用的函數(shù)
xhr.onreadystatechange = onReadyStateChange;
function onReadyStateChange() {
  // do something
}

// 方法二 使用匿名函數(shù)
xhr.onreadystatechange = function(){
    // do the thing
};

接下來我們需要在內(nèi)部利用 readyState 屬性來獲取當(dāng)前的狀態(tài),當(dāng) readyState 的值為 4,就意味著一個完整的服務(wù)器響應(yīng)已經(jīng)收到了,接下來就可以處理該響應(yīng):

// readyState的取值如下
// 0 (未初始化)
// 1 (正在裝載)
// 2 (裝載完畢)
// 3 (交互中)
// 4 (完成)
if (xhr.readyState === 4) {
    // everything is good, the response is received
} else {
    // still not ready
}

完整代碼如下:

// POST
var xhr;
if (window.XMLHttpRequest) { // Mozilla, Safari...
  xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
  try {
    xhr = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
  }
}
if (xhr) {
  xhr.onreadystatechange = onReadyStateChange;
  xhr.open("POST", "/api", true);
  // 設(shè)置 Content-Type 為 application/x-www-form-urlencoded
  // 以表單的形式傳遞數(shù)據(jù)
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  xhr.send("username=admin&password=root");
}


// onreadystatechange 方法
function onReadyStateChange() {
  // 該函數(shù)會被調(diào)用四次
  console.log(xhr.readyState);
  if (xhr.readyState === 4) {
    // everything is good, the response is received
    if (xhr.status === 200) {
      console.log(xhr.responseText);
    } else {
      console.log("There was a problem with the request.");
    }
  } else {
    // still not ready
    console.log("still not ready...");
  }
}

當(dāng)然我們可以用onload來代替onreadystatechange等于4的情況,因?yàn)閛nload只在狀態(tài)為4的時候才被調(diào)用,代碼如下:

xhr.onload = function () {    // 調(diào)用onload
    if (xhr.status === 200) {    // status為200表示請求成功
        console.log("執(zhí)行成功");
    } else {
        console.log("執(zhí)行出錯");
    }
}

然而需要注意的是,IE對 onload 屬性的支持并不友好。除了 onload 還有以下幾個屬性也可以用來監(jiān)測響應(yīng)狀態(tài):

onloadstart

onprogress

onabort

ontimeout

onerror

onloadend

二、 jQuery 實(shí)現(xiàn) AJAX

jQuery 作為一個使用人數(shù)最多的庫,其 AJAX 很好的封裝了原生 AJAX 的代碼,在兼容性和易用性方面都做了很大的提高,讓 AJAX 的調(diào)用變得非常簡單。下面便是一段簡單的 jQuery 的 AJAX 代碼:

$.ajax({
  method: "POST",
  url: "/api",
  data: { username: "admin", password: "root" }
})
  .done(function(msg) {
    alert( "Data Saved: " + msg );
  });

對比原生 AJAX 的實(shí)現(xiàn),使用 jQuery 就異常簡單了。當(dāng)然我們平時用的最多的,是下面兩種更簡單的方式:

// GET
$.get("/api", function(res) {
  // do something
});

// POST
var data = {
  username: "admin",
  password: "root"
};
$.post("/api", data, function(res) {
  // do something
});
三、Fetch API

使用 jQuery 雖然可以大大簡化 XMLHttpRequest 的使用,但 XMLHttpRequest 本質(zhì)上但并不是一個設(shè)計(jì)優(yōu)良的 API:

不符合關(guān)注分離(Separation of Concerns)的原則

配置和調(diào)用方式非?;靵y

使用事件機(jī)制來跟蹤狀態(tài)變化

基于事件的異步模型沒有現(xiàn)代的 Promise,generator/yield,async/await 友好

Fetch API 旨在修正上述缺陷,它提供了與 HTTP 語義相同的 JS 語法,簡單來說,它引入了 fetch() 這個實(shí)用的方法來獲取網(wǎng)絡(luò)資源。

Fetch 的瀏覽器兼容圖如下:

原生支持率并不高,幸運(yùn)的是,引入下面這些 polyfill 后可以完美支持 IE8+:

由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham

引入 Promise 的 polyfill: es6-promise

引入 fetch 探測庫:fetch-detector

引入 fetch 的 polyfill: fetch-ie8

可選:如果你還使用了 jsonp,引入 fetch-jsonp

可選:開啟 Babel 的 runtime 模式,現(xiàn)在就使用 async/await

1. 一個使用 Fetch 的例子

先看一個簡單的 Fetch API 的例子 ? :

fetch("/api").then(function(response) {
  return response.json();
}).then(function(data) {
  console.log(data);
}).catch(function(error) {
  console.log("Oops, error: ", error);
});

使用 ES6 的箭頭函數(shù)后:

fetch("/api").then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log("Oops, error: ", error))

可以看出使用Fetch后我們的代碼更加簡潔和語義化,鏈?zhǔn)秸{(diào)用的方式也使其更加流暢和清晰。但這種基于 Promise 的寫法還是有 Callback 的影子,我們還可以用 async/await 來做最終優(yōu)化:

async function() {
  try {
    let response = await fetch(url);
    let data = response.json();
    console.log(data);
  } catch (error) {
    console.log("Oops, error: ", error);
  }
}

使用 await 后,寫代碼就更跟同步代碼一樣。await 后面可以跟 Promise 對象,表示等待 Promise resolve() 才會繼續(xù)向下執(zhí)行,如果 Promise 被 reject() 或拋出異常則會被外面的 try...catch 捕獲。

Promise,generator/yield,await/async 都是現(xiàn)在和未來 JS 解決異步的標(biāo)準(zhǔn)做法,可以完美搭配使用。這也是使用標(biāo)準(zhǔn) Promise 一大好處。

2. 使用 Fetch 的注意事項(xiàng)

Fetch 請求默認(rèn)是不帶 cookie,需要設(shè)置 fetch(url, {credentials: "include"})`

服務(wù)器返回 400,500 錯誤碼時并不會 reject,只有網(wǎng)絡(luò)錯誤這些導(dǎo)致請求不能完成時,fetch 才會被 reject

接下來將上面基于 XMLHttpRequest 的 AJAX 用 Fetch 改寫:

var options = {
    method: "POST",
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ username: "admin", password: "root" }),
    credentials: "include"
  };

fetch("/api", options).then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log("Oops, error: ", error))

Github Issue: https://github.com/nodejh/nodejh.github.io/issues/15

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86672.html

相關(guān)文章

  • Jquery ajax, Axios, Fetch區(qū)別之我見

    摘要:我們都知道因?yàn)橥床呗缘膯栴},瀏覽器的請求是可能隨便跨域的一定要有跨域頭或者借助,但是,中可以設(shè)置為不跨域,如下所示這樣之后我們會得到一個為的返回。 免費(fèi)幫忙內(nèi)推阿里等各大IT公司的崗位,有興趣可以帶簡歷加微信angeltune 引言 前端技術(shù)真是一個發(fā)展飛快的領(lǐng)域,我三年前入職的時候只有原生XHR和Jquery ajax,我們還曾被JQuery 1.9版本版本以下不支持大文件請求這個...

    YanceyOfficial 評論0 收藏0
  • 全面分析前端的網(wǎng)絡(luò)請求方式

    摘要:請求默認(rèn)會攜帶同源請求的,而跨域請求則不會攜帶,設(shè)置的的屬性為將允許攜帶跨域。類型請求成功后的回調(diào)函數(shù)。另外,同樣提供了在環(huán)境下的支持,可謂是網(wǎng)絡(luò)請求的首選方案。當(dāng)網(wǎng)絡(luò)故障時或請求被阻止時,才會標(biāo)記為,如跨域不存在,網(wǎng)絡(luò)異常等會觸發(fā)。 一、前端進(jìn)行網(wǎng)絡(luò)請求的關(guān)注點(diǎn) 大多數(shù)情況下,在前端發(fā)起一個網(wǎng)絡(luò)請求我們只需關(guān)注下面幾點(diǎn): 傳入基本參數(shù)(url,請求方式) 請求參數(shù)、請求參數(shù)類型 設(shè)...

    Edison 評論0 收藏0
  • 只知道ajax?你已經(jīng)out了

    摘要:所以本文將介紹兩個目前常用的獲取服務(wù)器數(shù)據(jù)的庫和。隨著作者尤雨溪發(fā)布消息,不再繼續(xù)維護(hù)并推薦大家使用開始,進(jìn)入了很多人的目光。脫離了,是基于設(shè)計(jì)。如果要詳細(xì)了解的應(yīng)用,推薦閱讀教程和規(guī)范。歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~ 本文由前端林子發(fā)表于云+社區(qū)專欄 隨著前端技術(shù)的發(fā)展,請求服務(wù)器數(shù)據(jù)的方法早已不局限于ajax、jQuery的ajax方法。各種js庫已如雨后...

    Steven 評論0 收藏0
  • 前端培訓(xùn)-中級階段(9)- 原生Ajax的運(yùn)行原理與實(shí)現(xiàn)(2019-08-08期)

    摘要:前端最基礎(chǔ)的就是。的原理瀏覽器發(fā)送請求,服務(wù)器給出響應(yīng)。保持之前的界面不變化。的核心創(chuàng)建一個對象,用于發(fā)起請求設(shè)置為請求,請求發(fā)送請求。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識的中心思想,我們開課啦(每周四)。 ajax ...

    anonymoussf 評論0 收藏0
  • 前端培訓(xùn)-中級階段(9)- 原生Ajax的運(yùn)行原理與實(shí)現(xiàn)(2019-08-08期)

    摘要:前端最基礎(chǔ)的就是。的原理瀏覽器發(fā)送請求,服務(wù)器給出響應(yīng)。保持之前的界面不變化。的核心創(chuàng)建一個對象,用于發(fā)起請求設(shè)置為請求,請求發(fā)送請求。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識的中心思想,我們開課啦(每周四)。 ajax ...

    TANKING 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<