前端培訓-中級階段(9)- 原生Ajax的運行原理與實現(2019-08-08期)

前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,現在前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS),本着提升技術水平,打牢基礎知識的中心思想,我們開課啦(每週四)。

ajax 對於現在的前端來說已經是一件必需品了。單頁應用?前後端分離?遠程搜索?異步加載?能做的功能太多了。
當然,一直以來我們都是用一些封裝好的api去使用(jQuery.ajaxaxios)。今天我們就來了解原生的Ajax。

Ajax是什麼?

Asynchronous JavaScript + XML(異步JavaScript和XML), 其本身不是一種技術,而是一個在 2005年被Jesse James Garrett提出的新術語,用來描述一種使用現有技術集合的‘新’方法,包括: HTML or XHTML, Cascading Style Sheets, JavaScript, The Document Object Model, XML, XSLT, 以及最重要的 XMLHttpRequest object。當使用結合了這些技術的AJAX模型以後, 網頁應用能夠快速地將增量更新呈現在用戶界面上,而不需要重載(刷新)整個頁面。這使得程序能夠更快地迴應用戶的操作。

儘管X在Ajax中代表XML, 但由於JSON的許多優勢,比如更加輕量以及作爲Javascript的一部分,目前JSON的使用比XML更加普遍。JSON和XML都被用於在Ajax模型中打包信息。

Ajax的原理

瀏覽器發送請求 HttpRequest,服務器給出響應 HttpResponse。不同於正常打開頁面的是,Ajax通常使用的數據需要二次加工
比如一首歌的歌曲信息,使用Ajax加載到之後,我們再通過一定的方式把數據顯示在頁面之上。

當然,我們的html頁面,也是通過這樣的原理展示的,只不過是瀏覽器去拉,然後解析html,渲染給我們看。

Ajax的優點

  1. 速度更快。同等條件下,降低了流量,減少了無用數據的加載。
  2. 流量少。一個html和一個json那個更小,我就不說了吧。
  3. 保持之前的界面不變化。比如說驗證碼,比如說異步加載等等。可以保留歷史的輸入。

Ajax的核心API

  1. XMLHttpRequest

    1. var xhr= new XMLHttpRequest(); 創建一個XHR對象,用於發起請求
    2. xhr.open('GET', 'https://www.lilnong.top/static/json/manifest.json'); 設置爲GET請求,請求https://www.lilnong.top/stati...
    3. xhr.send(); 發送請求。這個時候瀏覽器會開啓一個線程去請求,回調函數會放在等待隊列中。
    4. 回調函數

      1. onload
      2. onerror
      3. abort
      4. onreadystatechange
  2. Fetch
    一個比 XHR 更的 API。支持 Promise,簡直不要太爽。

     fetch('https://www.lilnong.top/static/json/manifest.json')
         .then(response=>response.json())
         .then(data=>console.log(data));

XMLHttpRequest

之前我們已經大體的瞭解一下XHR,下面我們深入的介紹一下。測試地址,可以點按鈕,然後看network中的請求

new 一個 XHR 對象

new XMLHttpRequest();無參

老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 對象:new ActiveXObject("Microsoft.XMLHTTP");。話說兼容ie,還不用jquery的人很少吧。

使用 XHR 對象發送請求

xhr = new XMLHttpRequest();
xhr.open("GET","https://www.lilnong.top/static/json/front-end.json",true);
xhr.send();

open(method,url,async)

設置一個請求

  1. methods爲請求類型。參數如 GET POST PUT DELETE HEAD
  2. url爲請求地址。
  3. async。true(異步) false(同步)。

send(params)

發送這個請求,如果是post的話,參數是body的內容。get的話,需要帶在open的url上。

  1. 支持String
  2. FormData
  3. blob

設置請求頭 setRequestHeader

xhr.setRequestHeader(key,value);
通常有幾種情況我們需要設置。

  1. 上傳
    setRequestHeader("Content-type","application/x-www-form-urlencoded");這樣設置等於砸場子。肯定不支持。
    那麼常用的Content-type有什麼呢?分別對應的數據是什麼呢?留個作業吧(畢竟我之前寫過)
  2. token 驗證
    一般名字都是自定義的。登錄的token。csrf 的 token。

響應

一般來說就是拿到 response 來處理了。因爲這些都是和後端協商好的。JSON、XML、或者其他數據。
可以返回ArrayBuffer、Blob、Document、DOMString,具體是哪種類型取決於XMLHttpRequest.responseType的值。

readyState

每當 readyState 改變時,就會觸發 onreadystatechange 事件。標明當前XHR的狀態,onreadystatechange 事件被觸發 4 次(0 - 4), 分別是: 0-1、1-2、2-3、3-4,對應着 readyState 的每個變化。
0: 請求未初始化
1: 服務器連接已建立
2: 請求已接收
3: 請求處理中
4: 請求已完成,且響應已就緒(status爲返回的狀態碼)

回調

  1. onload 請求成功
  2. onerror 請求失敗
  3. onreadystatechange readyState 改變時
  4. progress 下載進度
  5. .upload.progress 上傳進度
  6. ontimeout 超時
  7. onabort 被終止

其他 屬性&方法

  1. timeout
    unsigned long 即無符號長整型,表示該請求的最大請求時間(毫秒),超過該時間請求會自動結束。
  2. withCredentials
    Boolean,用來指定跨域的請求是否應該使用證書(如cookie或授權header頭)。
  3. .abort()
    如果請求已經被髮送,則立刻中止請求.
  4. .getResponseHeader()
    返回包含指定響應頭的字符串,如果響應尚未收到或響應中不存在該報頭,則返回null。
    可以用來拿服務器時間

fetch

fetch --mdn,感興趣的可以去看看,我這裏只簡單介紹。畢竟這個api還需要發展。

但是promise真的好爽寫起來真的好短支持的返回類型也好多。還有就是新的API基本都是想要跨平臺(想想axios)。

Window 和 WorkerGlobalScope 都實現了 WorkerOrGlobalScope。——這意味着基本在任何場景下只要你想獲取資源,都可以使用 位於 WorkerOrGlobalScope 中的 fetch() 方法。

創建&發送

fetch(input[, init]);
input是你想要請求的資源。支持兩種類型

  1. 一個 USVString 字符串,包含要獲取資源的 URL。一些瀏覽器會接受 blob: 和 data: 作爲 schemes.
  2. 一個 Request 對象。

init就是一些參數

  1. method 請求使用的方法,如 GET、POST。
  2. headers 請求的頭信息,形式爲 Headers 的對象或包含 ByteString 值的對象字面量。
  3. body 請求的 body 信息:可能是一個 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 對象。注意 GET 或 HEAD 方法的請求不能包含 body 信息。
  4. 等等,還有好多,可以去MDN查看

HTTP response codes

附上MDN原文地址,我只列舉一些常見的。
簡單來說分爲五類

  1. 1xx 消息響應
  2. 2xx 成功響應
  3. 3xx 重定向
  4. 4xx 客戶端錯誤
  5. 5xx 服務器端錯誤
狀態碼 狀態描述 詳細描述 常見場景
200 OK (成功) 請求成功.成功的意義根據請求所使用的方法不同而不同.GET: 資源已被提取,並作爲響應體傳回客戶端.HEAD: 實體頭已作爲響應頭傳回客戶端.POST: 經過服務器處理客戶端傳來的數據,適合的資源作爲響應體傳回客戶端.TRACE: 服務器收到請求消息作爲響應體傳回客戶端.PUT、DELETE、OPTIONS 方法永遠不會返回 200 狀態碼. 加載網頁,加載資源,加載成功,可以說最常見
206 Partial Content (部分內容) 當客戶端通過使用range頭字段進行文件分段下載時使用該狀態碼 一般出現在大文件,比如MP4
301 Moved Permanently (永久移動) 該狀態碼錶示所請求的URI資源路徑已經改變,新的URL會在響應的Location:頭字段裏找到. 用於永久移動,比如說http跳轉到https,比如想要更換域名。通常搜索引擎爬蟲抓到301會替換保存的資源地址。
302 Found (臨時移動) 該狀態碼錶示所請求的URI資源路徑臨時改變,並且還可能繼續改變.因此客戶端在以後訪問時還得繼續使用該URI.新的URL會在響應的Location:頭字段裏找到 用於臨時重定向,比如登錄失效需要去登錄頁,比如作品目前在審覈。
304 Not Modified(未修改) 告訴客戶端,所請求的內容距離上次訪問並沒有變化. 客戶端可以直接從瀏覽器緩存裏獲取該資源. 一般就是js被緩存,css被緩存。當然也有寫get請求數據接口也會緩存。
400 Bad Request(錯誤請求) 因發送的請求語法錯誤,服務器無法正常讀取. 一般來說都是body數據異常,比如服務端要params,body裏面是JSON
401 Unauthorized(未授權) 需要身份驗證後才能獲取所請求的內容,類似於403錯誤.不同點是.401錯誤後,只要正確輸入帳號密碼,驗證即可通過.
403 Forbidden(禁止訪問) 客戶端沒有權利訪問所請求內容,服務器拒絕本次請求. 通常都是token失效
404 Not Found(未找到) 服務器找不到所請求的資源.由於經常發生此種情況,所以該狀態碼在上網時是非常常見的. 接口未定義,資源不存在
500 Internal Server Error (內部服務器錯誤) 服務器遇到未知的無法解決的問題.
501 Implemented (未實現) 服務器不支持該請求中使用的方法,比如POST 和 PUT.只有GET 和 HEAD 是RFC2616規範中規定服務器必須實現的方法.
502 Bad Gateway (網關錯誤) 服務器作爲網關且從上游服務器獲取到了一個無效的HTTP響應.
503 Service Unavailable (服務不可用) 由於臨時的服務器維護或者過載,服務器當前無法處理請求.這個狀況是臨時的,並且將在一段時間以後恢復.如果能夠預計延遲時間,那麼響應中可以包含一個Retry-After:頭用以標明這個延遲時間.如果沒有給出這個Retry-After:信息,那麼客戶端應當以處理500響應的方式處理它.同時,這種情況下,一個友好的用於解釋服務器出現問題的頁面應當被返回,並且,緩存相關的HTTP頭信息也應該包含,因爲通常這種錯誤提示網頁不應當被客戶端緩存.
504 Gateway Timeout (網關超時) 服務器作爲網關且不能從上游服務器及時的得到響應返回給客戶端.

微信公衆號:前端linong

clipboard.png

初級階段文章目錄

  1. 前端培訓-初級階段(17) - 數據存儲(cookie、session、stroage)
  2. 前端培訓-初級階段(13) - 正則表達式
  3. 前端培訓-初級階段(13) - 類、模塊、繼承
  4. 前端培訓-初級階段(13) - ECMAScript (內置對象、函數)
  5. 前端培訓-初級階段(13) - ECMAScript (語法、變量、值、類型、運算符、語句)
  6. 前端培訓-初級階段(13、18)
  7. 前端培訓-初級階段(9 -12)
  8. 前端培訓-初級階段(5 - 8)
  9. 前端培訓-初級階段(1 - 4)

中級階段文章目錄

  1. 前端培訓-中級階段(2) - 事件(event) 事件冒泡、捕獲 - (2019-06-20期)
  2. 前端培訓-中級階段(3) - DOM 文檔對象模型(2019-06-27期)
  3. 前端培訓-中級階段(4)- BOM 瀏覽器對象模型(2019-07-04期)
  4. 前端培訓-中級階段(5)- jQuery的概念與基本使用(2019-07-11期)
  5. 前端培訓-中級階段(6)- jQuery元素節點操作(2019-07-18期)
  6. 前端培訓-中級階段(7)- jQuery的事件綁定鏈式操作及原理(2019-07-25期)
  7. 前端培訓-中級階段(8)- jQuery元素屬性樣式操作(2019-08-01期)

資料

  1. 前端培訓目錄、前端培訓規劃、前端培訓計劃
  2. XMLHttpRequest
  3. XMLHttpRequest.upload
  4. XMLHttpRequest.readyState
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章