javascript
七、前端开发-JavaScript HTTP
七、前端開發語言體系-JavaScript HTTP
文章目錄
- 七、前端開發語言體系-JavaScript HTTP
- JavaScript AJAX
- AJAX簡介
- AJAX-XMLHttp
- AJAX請求
- AJAX響應
- JavaScript JSONP
- JSONP簡介
- JSONP原理
- JSONP具體實現
- JavaScript Promise
- Promise簡介
- Promise特點
- Promise用法
- 參考文章
JavaScript AJAX
AJAX簡介
AJAX = Asynchronous JavaScript And XML.
AJAX 不是編程語言,它僅僅組合了:
- 瀏覽器內建的 XMLHttpRequest 對象(從 web 服務器請求數據)
- JavaScript 和 HTML DOM(顯示或使用數據)
Ajax 允許通過與場景后面的 Web 服務器交換數據來異步更新網頁。這意味著可以更新網頁的部分,而不需要重新加載整個頁面。
AJAX工作流程:
AJAX-XMLHttp
Ajax 的核心是 XMLHttpRequest 對象。
所有現代瀏覽器(Chrome、IE7+、Firefox、Safari 以及 Opera)都支持 XMLHttpRequest 對象。XMLHttpRequest 對象用于同幕后服務器交換數據。這意味著可以更新網頁的部分,而不需要重新加載整個頁面。
創建 XMLHttpRequest 對象的語法是:
variable = new XMLHttpRequest();因為IE5、IE6使用的是 ActiveX 對象,為了應對所有瀏覽器,請檢查瀏覽器是否支持 XMLHttpRequest 對象。如果支持,創建 XMLHttpRequest 對象,如果不支持,則創建 ActiveX 對象。
var xhttp; if (window.XMLHttpRequest) {xhttp = new XMLHttpRequest(); } else {// code for IE6, IE5xhttp = new ActiveXObject("Microsoft.XMLHTTP"); }出于安全原因,現代瀏覽器不允許跨域訪問。這意味著嘗試加載的網頁和 XML 文件都必須位于相同服務器上。
如果您希望在自己的頁面上使用以上實例,那么您所加載的 XML 文件必須位于您自己的服務器上。
XMLHttpRequest 對象常用的方法和屬性:
| new XMLHttpRequest() | 創建新的 XMLHttpRequest 對象 | onreadystatechange | 定義當 readyState 屬性發生變化時被調用的函數 |
| getAllResponseHeaders() | 返回頭部信息 | readyState | 保存 XMLHttpRequest 的狀態,從0-4變化。0:請求未初始化,1:服務器連接已建立,2:請求已收到,3:正在處理請求,4:請求已完成且響應已就緒 |
| open(method, url, async) | 規定請求的類型、URL和是否異步處理請求。method:請求類型 GET 或 POST,url:文件位置,async:true(異步)或 false(同步) | responseText | 以字符串返回響應數據 |
| send() | 將請求發送到服務器,用于 GET 請求 | responseXML | 以 XML 數據返回響應數據 |
| send(string) | 將請求發送到服務器,用于 POST 請求 | status | 返回請求的狀態號。200: “OK”,404: “Not Found” |
| setRequestHeader(header, value) | 向要發送的報頭添加標簽/值對。header:規定頭部名稱,value:規定頭部值 | statusText | 返回狀態文本(例如 “OK” 或 “Not Found”) |
AJAX請求
向服務器發送請求,我們使用 XMLHttpRequest 對象的 open() 和 send() 方法。
至于請求類型使用 GET 還是 POST,一般我們使用 GET,因為 GET 比 POST 更簡單更快速,適用于絕大多數場景。
不過,請在以下情況始終使用 POST:
- 緩存文件不是選項(更新服務器上的文件或數據庫)
- 向服務器發送大量數據(POST 無大小限制)
- 發送用戶輸入(可包含未知字符),POST 比 GET 更強大更安全
一條簡單的 GET 請求:
xhttp.open("GET", "demo_get.asp", true); xhttp.send();一條簡單的 POST 請求:
xhttp.open("POST", "demo_post.asp", true); xhttp.send();open( ) 方法的 url 參數,是服務器上文件的地址。該文件可以是任何類型的文件,如 .txt 和 .xml,或服務器腳本文件,如 .asp 和 .php(它們可以在發送回響應之前在服務器執行操作)。
xhttp.open("GET", "ajax_test.asp", true);open( ) 方法的 async 參數設置為 true 表示異步發送請求。通過異步發送,JavaScript 不必等待服務器響應,可以在等待服務器響應時執行其他腳本,當響應就緒時處理響應。
false 表示同步發送請求,一般不推薦同步的 XMLHttpRequest,因為 JavaScript 將停止執行直到服務器響應就緒。如果服務器繁忙或緩慢,應用程序將掛起或停止。
xhttp.open("GET", "ajax_test.asp", true);通過 XMLHttpRequest 對象,我們可以定義當請求接收到應答時所執行的函數。
xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {document.getElementById("demo").innerHTML = this.responseText;} }; xhttp.open("GET", "ajax_info.txt", true); xhttp.send();AJAX響應
- readyState 屬性存留 XMLHttpRequest 的狀態。
- onreadystatechange 屬性定義當 readyState 發生變化時執行的函數。
- status 屬性和 statusText 屬性存有 XMLHttpRequest 對象的狀態。
每當 readyState 發生變化時就會調用 onreadystatechange 函數。
//當 readyState 為 4,status 為 200 時,響應就緒 function loadDoc() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {document.getElementById("demo").innerHTML =this.responseText;}};xhttp.open("GET", "ajax_info.txt", true);xhttp.send(); }回調函數是一種作為參數被傳遞到另一個函數的函數。
如果您的網站中有多個 AJAX 任務,那么您應該創建一個執行 XMLHttpRequest 對象的函數,以及一個供每個 AJAX 任務的回調函數。該函數應當包含 URL 以及當響應就緒時調用的函數。
loadDoc("url-1", myFunction1);loadDoc("url-2", myFunction2);function loadDoc(url, cFunction) {var xhttp;xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {cFunction(this);}};xhttp.open("GET", url, true);xhttp.send(); }function myFunction1(xhttp) {// action goes here } function myFunction2(xhttp) {// action goes here }- getAllResponseHeaders() 方法返回所有來自服務器響應的頭部信息。
- getResponseHeader() 方法返回來自服務器響應的特定頭部信息。
JavaScript JSONP
JSONP簡介
注意 JSONP 和 JSON 不一樣,這里先提一下 JSON 的概念。
JSON是一種輕量級的數據傳輸格式,被廣泛應用于當前Web應用中。JSON格式數據的編碼和解析基本在所有主流語言中都被實現,所以現在大部分前后端分離的架構都以JSON格式進行數據的傳輸。
為了保證用戶訪問的安全,現代瀏覽器使用了同源策略,不允許訪問非同源的頁面,即不允許跨域訪問。如果兩個頁面中的協議、域名、端口、子域名任意有一項不同,兩者之間所進行的訪問行動就是跨域的。
ajax跨域只是屬于瀏覽器”同源策略”中的一部分,這里我們僅討論 ajax 跨域問題。解決 ajax 跨域常用的有兩個方式:
- JSONP方式
- CORS方式
JSONP(JSON Padding) 是 JSON 的一種"使用模式",可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。JSONP 并不是 JSON,它是為了解決跨域請求而提出的概念。
CORS 與 JSONP的使用目的相同,但是比 JSONP 更強大。CORS需要瀏覽器和服務器同時支持。目前,所有主流瀏覽器都支持該功能,IE瀏覽器不能低于IE10。
JSONP 只支持 GET 請求,CORS 支持所有類型的 HTTP 請求。JSONP 的優勢在于支持老式瀏覽器,以及可以向不支持 CORS 的網站請求數據。
想對 CORS 進行詳細探究的請參考這篇博客 跨域資源共享 CORS 詳解,這里我們著重介紹 JSONP。
JSONP原理
因為 script 標簽 src 屬性中的鏈接卻可以訪問跨域的 JS 腳本,所以我們利用 script 標簽沒有跨域限制的“漏洞”來達到與第三方通訊的目的。
當需要通訊時,本站腳本創建一個 script 元素,地址指向第三方的API網址,并創建一個回調函數(callback)來接收數據。第三方產生的響應是 JSON 數據的包裝(即JSONP),這樣瀏覽器會調用callback函數,并傳遞解析后json對象作為參數。本站腳本可在callback函數里處理所傳入的數據。
JSONP具體實現
動態的添加了一個 script 標簽, src 指向跨域的一個 php 腳本,并且將 js 函數名作為 callback 參數傳入。
//前端代碼 <!DOCTYPE html> <html> <head><title>GoJSONP</title> </head> <body> <script type="text/javascript" src="https://cdn.staticfile.org/jquery/2.2.4/jquery.min.js"> </script> <script type="text/javascript">function jsonhandle(data){alert("age:" + data.age + "name:" + data.name);} </script> <script type="text/javascript">$(document).ready(function(){var url = "http://www.practice-zhao.com/student.php?id=1&callback=jsonhandle";var obj = $('<script><\/script>');obj.attr("src",url);$("body").append(obj);}); </script> </body> </html> //PHP代碼 <?php $data = array('age' => 20,'name' => '張三', );$callback = $_GET['callback'];echo $callback."(".json_encode($data).")"; return; ?>PHP代碼返回了一段JS語句,即
jsonhandle({"age" : 15,"name": "張三", })運行代碼之后,瀏覽器會彈窗提示:
其實 jQuery 提供了方便使用 JSONP 的方式,推薦使用這一種方式:
<!DOCTYPE html> <html> <head><title>JSONP</title><meta charset="utf-8"><script type="text/javascript" src="https://cdn.staticfile.org/jquery/2.2.4/jquery.min.js"></script> </head> <body><p>JSONP測試跨域</p><p id="ceshi"></p><script type="text/javascript">function demo(data){document.getElementById("ceshi").innerHTML = data.name+" is "+data.age+" age";}</script><script src="test.json?callback=demo"></script> </body> </html>test.json文件與 html文件在同一目錄下
demo( {"name":"Bob","age":23 })注意:
JavaScript Promise
Promise簡介
JavaScript是單線程語言,所有代碼都是單線程執行的。由于這個“缺陷”,導致JavaScript的所有網絡操作,瀏覽器事件,都必須是異步執行。
但是過多的回調會導致“回調地獄”,代碼既不美觀,也不易維護,所以就有了Promise。
Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理且更強大。它最早由社區提出并實現,ES6將其寫進了語言標準,統一了用法,并原生提供了Promise對象。
Promise特點
Promise 是一個對象,是用來處理異步操作的。Promise 顧名思義為承諾、許諾的意思,意思是使用了 Promise 之后他肯定會給我們答復,無論成功或者失敗都會給我們一個答復。
Promise 對象一共有三種狀態,對象的狀態不受外界影響,一旦狀態改變就不會再變。
- Pending 狀態(進行中)
- Fulfilled 狀態(已成功)
- Rejected 狀態(已失敗)
Promise 的過程一般只有兩種:
- Pending -> Fulfilled
- Pending -> Rejected
Promise 優缺點
| 解決回調 | 無法監測進行狀態 |
| 鏈式調用 | 新建立即執行且無法取消 |
| 減少嵌套 | 內部錯誤無法拋出 |
如果對“鏈式調用”不清楚的,請參考這篇博客 鏈式調用方法的實現原理和方法
Promise用法
Promise構造函數接受一個函數作為參數,該函數的兩個參數分別是resolve和reject。它們是兩個函數,由JavaScript引擎提供,不用自己部署。
Promise 對象有一個比較常用的 then 方法,用來執行回調函數。then 方法可以接受兩個回調函數作為參數。
執行后,我們發現輸出順序總是 AAA -> CCC -> BBB。這是因為,在 Promise 新建后會立即執行,所以首先輸出 AAA。然后,then 方法指定的回調函數將在當前腳本所有同步任務執行完后才會執行,所以 會接著輸出 CCC,最后輸出 BBB。
Promise 與定時器混用:
let promise = new Promise(function(resolve, reject){console.log("1");resolve(); }); setTimeout(()=>console.log("2"), 0); promise.then(() => console.log("3")); console.log("4");// 輸出為:1 4 3 21與4的順序不必再說,而2與3先輸出Promise的then,而后輸出定時器任務。原因則是Promise屬于JavaScript引擎內部任務,而setTimeout則是瀏覽器API,而引擎內部任務優先級高于瀏覽器API任務,所以有此結果。
Promise 常用API:
參考文章
W3School-JavaScript AJAX
javascript中ajax的四大步驟
js—JSONP原理及使用
【JavaScript】通過封裝自己的JSONP解決瀏覽器的跨域問題(Ajax跨域)
JS執行——Promise - 簡書
js promise看這篇就夠了
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的七、前端开发-JavaScript HTTP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 六、前端开发-JavaScript DO
- 下一篇: 八、前端开发-JavaScript 客户