- 同步、異步請求
- 點擊一個超鏈接搓逾、打開一個網(wǎng)站都屬于同步請求
- JSP卷谈、ASP大多數(shù)情況屬于混編模式,通過事件觸發(fā)http請求霞篡,服務器根據(jù)請求的參數(shù)世蔗,重新組裝頁面,然后將頁面返回給瀏覽器朗兵。這種屬于混編+同步請求污淋,
Ajax
- ajax全稱:Async javascript and xml表示異步的js和xml
- readyState代表http請求處于哪個階段
- status代表http狀態(tài)碼
function xhrequest (url) {
let xhr = null;
if (XMLHttpRequest) { // 使用XMLHttpRequest實例化對象可以操作ajax
xhr = new XMLHttpRequest();
} else { // ie5 ie6 需要使用ActiveXObject
xhr = new ActiveXObejct("Microsoft.XMLHTTP");
}
console.log(xhr.readyState); // 0 代表xhr未初始化
xhr.open('get', url, true); // true代表異步的方式,false代表同步
console.log(xhr.readyState); // 1 代表http連接已建立
xhr.send(); // 如果是post請求余掖,send里需要寫"a=1&b=2"格式的字符串參數(shù)寸爆,此方式為傳統(tǒng)的post表單格式,更多類型見1-1例盐欺。
xhr.onreadystatechange = () => {
console.log(xhr.readyState); // 2 代表請求已接受 3 代表請求處理中 4代表請求已處理完畢
console.log(xhr.status);
if(xhr.status == 200 && xhr.readyState == 4){
console.log(xhr.responseText);
}
}
}
xhrequest('http://www.webqd.top:8080');
function send(type) {
url = "http://127.0.0.1:8080/";
xhr = new XMLHttpRequest();
xhr.open("post", url, true);
var data;
if (type === "formdata") {
data = new FormData();
data.append("key", "value");
} else if (type === "json") {
xhr.setRequestHeader("Content-Type", "application/json");
data = JSON.stringify({"key": "value"});
} else if (type === "text") {
data = "key=value";
} else if (type === "www") {
// 這個header 其實是 傳統(tǒng)post 表單的格式
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
data = "key=value";
}
xhr.send(data);
}
封裝ajax
var $ = function (w) {
function formatData (data) {
if(!data) return null;
var str = '',
toStr = Object.prototype.toString;
for( var key in data ) {
if ( toStr.call(data[key]) === '[object Object]'
|| toStr.call(data[key]) === '[object Array]' ) {
// 待實現(xiàn)
}
str += key + '=' + data[key] + '&';
}
str = str.replace(/&$/, '');
return str;
}
function _doAjax(opt) {
var xhr = null;
if (w.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
opt = opt || {};
if (!opt.url) throw new Error("url為必填項");
let url = opt.url,
type = (opt.type || 'GET').toUpperCase(),
data = opt.data || null,
contentType = opt.contentType || 'application/x-www-form-urlencoded', // 只有post請求時赁豆,需要設置請求的數(shù)據(jù)類型
dataType = (opt.dataType || 'json').toLowerCase(), // 服務器返回的數(shù)據(jù)類型
async = (opt.async + '') === 'false' ? false : true,
timeout = opt.timeout || 30000, // 如果設置0,默認為30秒 todo:封裝其他類型 回調等
success = opt.success || function () {},
error = opt.error || function () {},
complete = opt.complete || function () {},
tId = null;
xhr.onreadystatechange = function () { // 此函數(shù)必須在send方法執(zhí)行前進行定義冗美,否則無法實現(xiàn)同步
if (xhr.readyState === 4) {
if (xhr.status === 304 || (xhr.status >= 200 && xhr.status < 300)) {
switch (dataType) {
case 'json':
success(JSON.parse(xhr.responseText));
break;
case 'text':
success(xhr.responseText);
break;
case 'xml':
case 'html':
success(xhr.responseXml);
break;
default :
success(xhr.responseText);
}
} else {
error(xhr.statusText);
}
clearTimeout(tId);
tId = null;
xhr = null;
complete("The request of " + url + " has completed");
}
}
tId = setTimeout(function () {
clearTimeout(tId);
xhr.abort(); // 終止已發(fā)出的請求
tId = null;
xhr = null;
throw new Error('The request has time out');
}, timeout);
xhr.open(type, url, async);
if (type === 'POST') xhr.setRequestHeader('Content-Type', contentType);
// xhr.setResponseType = dataType; // TOOD: 待優(yōu)化魔种,將xml html轉為document 設置blob、arrayBuffer粉洼、ms-stream务嫡、"" 類型
xhr.send(formatData(data)); // 如果是同步甲抖,send方法會等待readyState為4的時候才會繼續(xù)執(zhí)行后面的代碼
}
return {
ajax: function (options) {
_doAjax(options);
},
post: function (url, data, cb) {
this.ajax({
url: url,
type: 'post',
data: data,
success: cb,
});
},
get: function (url, cb) {
this.ajax({
url: url,
success: cb,
});
}
};
}(window);