原生ajax寫法-原生ajax請求-原生ajax實例

下面是來自百度百科的理解:
Ajax 即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML),是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。
說話的方式簡單點:就是Browser和Server之間通信的一種方式,發(fā)送以及請求數(shù)據(jù)的一種方式。
在AJAX出現(xiàn)之前:用戶每次與server進行一次交互都需要進入一個新的頁面。例如用戶點擊下一頁按鈕,會直接跳轉(zhuǎn)頁面,用戶明明只需要一部分的數(shù)據(jù),確需要重新向server請求整個頁面的數(shù)據(jù),那么很多數(shù)據(jù)是重復(fù)的相同的,造成了不必要的帶寬浪費,對server壓力也大。
AJAX 出現(xiàn)之后:用戶點擊下一頁按鈕,發(fā)起AJAX請求,只需要獲取第二頁的數(shù)據(jù),然后修改頁面局部的視圖,OVER。其最大的優(yōu)點是在不重新加載整個頁面的情況下,可以與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁內(nèi)容。
AJAX優(yōu)點:
1.無刷新更新數(shù)據(jù)。
無需重載整個頁面,按需請求部分數(shù)據(jù),節(jié)約帶寬,減少服務(wù)器壓力。
2.異步與服務(wù)器通信。
不會打斷用戶操作,有些用戶只需要首屏的搜索功能,就不必等到頁面全部加載完成。
提升瀏覽器渲染體驗,用戶會在server響應(yīng)數(shù)據(jù)之前看到整個頁面的大概框架以及結(jié)構(gòu)。
其實目的也是為了體驗好!體驗好!體驗好!
AJAX缺點:
1.瀏覽器的收藏功能在某些情況使用不便(用戶想收藏第二頁數(shù)據(jù)時)。瀏覽器的后退功能在某些情況使用不便(用戶退回第一頁時)。
2.AJAX的安全問題
AJAX相當于Browser和Server之間的一條通道,通過觀察server的響應(yīng)數(shù)據(jù)結(jié)構(gòu),在某些情況下回暴露出一些server的邏輯。黑客也可以模擬用戶向Server發(fā)起請求,出現(xiàn)了諸如跨站點腳步攻擊、SQL注入攻擊等
Ajax原生js實現(xiàn)
最簡單的實現(xiàn)方式:
var xhr = new XMLHttpRequest();
xhr.open('請求方式GET或者POST或者其他', 請求地址url, 是否開啟異步async);
xhr.onreadystatechange = function() {
// readyState == 4說明請求已完成
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
}
if (method == 'POST') {
//給指定的HTTP請求頭賦值
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.send()
目前已經(jīng)有很多的工具(類庫實現(xiàn)了AJAX的封裝),只會用當然不行,我們需要詳細的理解它的屬性內(nèi)容

XMLHttpRequest的屬性
onreadystatechange:值為一個
function,當readyState屬性改變時會調(diào)用它readyState:Http請求過程中的狀態(tài)值,具體情況如下
| 狀態(tài)值 | 描述 |
|---|---|
| 0 | 初始化狀態(tài)。XMLHttpRequest 對象已創(chuàng)建或已被 abort() 方法重置。 |
| 1 | open() 方法已調(diào)用,但是 send() 方法未調(diào)用。請求還沒有被發(fā)送。 |
| 2 | Send() 方法已調(diào)用,HTTP 請求已發(fā)送到 Web 服務(wù)器。未接收到響應(yīng)。 |
| 3 | 所有響應(yīng)頭部都已經(jīng)接收到。響應(yīng)體開始接收但未完成。 |
| 4 | HTTP 響應(yīng)已經(jīng)完全接收。 |
- responseText:目前為止收到的響應(yīng)體(不包括頭部),或者如果還沒有接收到數(shù)據(jù)的話,就是空字符串。
如果 readyState 小于 3,這個屬性就是一個空字符串。當 readyState 為 3,這個屬性返回目前已經(jīng)接收的響應(yīng)部分。如果 readyState 為 4,這個屬性保存了完整的響應(yīng)體。
如果響應(yīng)包含了為響應(yīng)體指定字符編碼的頭部,就使用該編碼。否則,假定使用 Unicode UTF-8。
responseXML
對請求的響應(yīng),解析為 XML 并作為 Document 對象返回。status
由服務(wù)器返回的 HTTP 狀態(tài)代碼,HTTP狀態(tài)碼整理。當 readyState 小于 3 的時候讀取這一屬性會導(dǎo)致一個異常。statusText
這個屬性用名稱而不是數(shù)字指定了請求的 HTTP 的狀態(tài)代碼。也就是說,當狀態(tài)為 200 的時候它是 "OK",當狀態(tài)為 404 的時候它是 "Not Found"。和 status 屬性一樣,當 readyState 小于 3 的時候讀取這一屬性會導(dǎo)致一個異常。
XMLHttpRequest的方法
-
open(method,url,async)
初始化一個請求。
注意: 在一個已經(jīng)激活的request下(已經(jīng)調(diào)用open()方法的request)再次調(diào)用這個方法相當于調(diào)用了abort()方法。
| 參數(shù) | 描述 |
|---|---|
| method | HTTP請求方式:"GET", "POST", "PUT", "DELETE"等 |
| url | 請求路徑 |
| async | 是否異步請求。值為布爾值,默認為true,如果值為false,則send()方法不會返回任何東西,直到接受到了服務(wù)器的返回數(shù)據(jù)。 |
abort()
取消當前響應(yīng),關(guān)閉連接并且結(jié)束任何未決的網(wǎng)絡(luò)活動。
這個方法把 XMLHttpRequest 對象重置為 readyState 為 0 的狀態(tài),并且取消所有未決的網(wǎng)絡(luò)活動。例如,如果請求用了太長時間,而且響應(yīng)不再必要的時候,可以調(diào)用這個方法。send(string)
發(fā)送 HTTP 請求。只有POST方式才傳參,參數(shù)類型為字符串。GET方式參數(shù)跟在url上setRequestHeader(header,value)
向一個打開但未發(fā)送的請求設(shè)置或添加一個 HTTP 請求(設(shè)置請求頭)。
注意:POST請求一般情況下需要設(shè)置請求頭
request對象.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
| 參數(shù) | 描述 |
|---|---|
| header | 設(shè)置的請求頭名稱 |
| value | 對應(yīng)的請求頭的值 |
getAllResponseHeaders()
把 HTTP 響應(yīng)頭部作為未解析的字符串返回。
如果 readyState 小于 3,這個方法返回 null。否則,它返回服務(wù)器發(fā)送的所有 HTTP 響應(yīng)的頭部。頭部作為單個的字符串返回,一行一個頭部。每行用換行符 "\r\n" 隔開。getResponseHeader(name)
返回指定的 HTTP 響應(yīng)頭部的值。其參數(shù)是要返回的 HTTP 響應(yīng)頭部的名稱。可以使用任何大小寫來制定這個頭部名字,和響應(yīng)頭部的比較是不區(qū)分大小寫的。
該方法的返回值是指定的 HTTP 響應(yīng)頭部的值,如果沒有接收到這個頭部或者 readyState 小于 3 則為空字符串。如果接收到多個有指定名稱的頭部,這個頭部的值被連接起來并返回,使用逗號和空格分隔開各個頭部的值。
試著封裝一下
以下是簡化版,僅概述原理
使用閉包來防止變量污染
const $ = (function() {
var name = 'jquery';
return {
ajax: function({
type,
url,
data,
isAsync,
success
}) {
if (!url) {
console.error('請輸入請求地址')
return;
}
var xhr = new XMLHttpRequest();
// 處理data對象
var query = [],
queryData;
for (var key in data) {
// 默認encodeURIComponent一下
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
queryData = query.join('&');
if (type == 'GET') {
// get方式參數(shù)要跟在url上
url = url + '?' + queryData
}
// 默認使用GET,默認異步
xhr.open(type || 'GET', url, isAsync || true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// 有傳入success回調(diào)就執(zhí)行
success && success(xhr.responseText);
}
}
if (type == 'POST') {
//給指定的HTTP請求頭賦值
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// 數(shù)組轉(zhuǎn)成字符串
xhr.send(queryData)
} else {
xhr.send()
}
}
}
})();
//類似jquery的使用方式
$.ajax({
type: 'POST',
url: 'https://web-api.juejin.im/gptzllpbev',
data: {
name: '嘻嘻'
},
success: function(res) {
console.log(res);
}
})