原生ajax寫法-原生ajax請求-原生ajax實(shí)例
下面是來自百度百科的理解:
Ajax 即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML)确垫,是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)谈截。
說話的方式簡單點(diǎn):就是Browser和Server之間通信
的一種方式滩字,發(fā)送以及請求數(shù)據(jù)
的一種方式沧卢。
在AJAX出現(xiàn)之前:用戶每次與server進(jìn)行一次交互都需要進(jìn)入一個新的頁面。例如用戶點(diǎn)擊下一頁按鈕
趁冈,會直接跳轉(zhuǎn)頁面剿配,用戶明明只需要一部分
的數(shù)據(jù)症见,確需要重新向server請求整個頁面
的數(shù)據(jù),那么很多數(shù)據(jù)是重復(fù)的相同的
捺弦,造成了不必要的帶寬浪費(fèi)饮寞,對server壓力也大孝扛。
AJAX 出現(xiàn)之后:用戶點(diǎn)擊下一頁按鈕
,發(fā)起AJAX請求幽崩,只需要
獲取第二頁的數(shù)據(jù)疗琉,然后修改頁面局部的視圖,OVER歉铝。其最大的優(yōu)點(diǎn)是在不重新加載整個頁面的情況下盈简,可以與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁內(nèi)容。
AJAX優(yōu)點(diǎn):
1.無刷新更新數(shù)據(jù)太示。
無需重載整個頁面柠贤,按需請求部分?jǐn)?shù)據(jù),節(jié)約帶寬类缤,減少服務(wù)器壓力臼勉。
2.異步與服務(wù)器通信。
不會打斷用戶操作餐弱,有些用戶只需要首屏的搜索功能宴霸,就不必等到頁面全部加載完成。
提升瀏覽器渲染體驗膏蚓,用戶會在server響應(yīng)數(shù)據(jù)之前看到整個頁面的大概框架以及結(jié)構(gòu)瓢谢。
其實(shí)目的也是為了體驗好!體驗好!體驗好!
AJAX缺點(diǎn):
1.瀏覽器的收藏功能在某些情況使用不便(用戶想收藏第二頁數(shù)據(jù)時)巡球。瀏覽器的后退功能在某些情況使用不便(用戶退回第一頁時)楔壤。
2.AJAX的安全問題
AJAX相當(dāng)于Browser和Server之間的一條通道,通過觀察server的響應(yīng)數(shù)據(jù)結(jié)構(gòu)维苔,在某些情況下回暴露出一些server的邏輯论笔。黑客也可以模擬用戶向Server發(fā)起請求采郎,出現(xiàn)了諸如跨站點(diǎn)腳步攻擊、SQL注入攻擊等
Ajax原生js實(shí)現(xiàn)
最簡單的實(shí)現(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)有很多的工具(類庫實(shí)現(xiàn)了AJAX的封裝)狂魔,只會用當(dāng)然不行蒜埋,我們需要詳細(xì)的理解它的屬性內(nèi)容
XMLHttpRequest的屬性
onreadystatechange:值為一個
function
,當(dāng)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,這個屬性就是一個空字符串胳搞。當(dāng) 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)碼整理般婆。當(dāng) readyState 小于 3 的時候讀取這一屬性會導(dǎo)致一個異常到腥。statusText
這個屬性用名稱而不是數(shù)字指定了請求的 HTTP 的狀態(tài)代碼。也就是說腺兴,當(dāng)狀態(tài)為 200 的時候它是 "OK"左电,當(dāng)狀態(tài)為 404 的時候它是 "Not Found"廉侧。和 status 屬性一樣页响,當(dāng) readyState 小于 3 的時候讀取這一屬性會導(dǎo)致一個異常。
XMLHttpRequest的方法
-
open(method,url,async)
初始化一個請求段誊。
注意: 在一個已經(jīng)激活的request下(已經(jīng)調(diào)用open()方法的request)再次調(diào)用這個方法相當(dāng)于調(diào)用了abort()方法闰蚕。
參數(shù) | 描述 |
---|---|
method | HTTP請求方式:"GET", "POST", "PUT", "DELETE"等 |
url | 請求路徑 |
async | 是否異步請求。值為布爾值 连舍,默認(rèn)為true,如果值為false,則send()方法不會返回任何東西没陡,直到接受到了服務(wù)器的返回數(shù)據(jù)。 |
abort()
取消當(dāng)前響應(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) {
// 默認(rèn)encodeURIComponent一下
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
queryData = query.join('&');
if (type == 'GET') {
// get方式參數(shù)要跟在url上
url = url + '?' + queryData
}
// 默認(rèn)使用GET,默認(rèn)異步
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);
}
})