- 同步、异步请求
- 点击一个超链接、打开一个网站都属于同步请求
- JSP、ASP大多数情况属于混编模式,通过事件触发http请求,服务器根据请求的参数,重新组装页面,然后将页面返回给浏览器。这种属于混编+同步请求,
Ajax
- ajax全称:Async javascript and xml表示异步的js和xml
- readyState代表http请求处于哪个阶段
- status代表http状态码
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"格式的字符串参数,此方式为传统的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 其实是 传统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]' ) {
// 待实现
}
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请求时,需要设置请求的数据类型
dataType = (opt.dataType || 'json').toLowerCase(), // 服务器返回的数据类型
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 () { // 此函数必须在send方法执行前进行定义,否则无法实现同步
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(); // 终止已发出的请求
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: 待优化,将xml html转为document 设置blob、arrayBuffer、ms-stream、"" 类型
xhr.send(formatData(data)); // 如果是同步,send方法会等待readyState为4的时候才会继续执行后面的代码
}
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);
网友评论