Ajax的原理:
一个简单的ajax
第一步:new XMLHttpRequest 对象。
第二步: open一个url
第三步: onreadstatechange 监听网络数据变化。
第四部: send数据。
var Ajax = {
get: function(url,fn){
// XMLHttpRequest对象用于在后台与服务器交换数据
var xhr = new XMLHttpRequest();
xhr.open('GET',url,false);
xhr.onreadystatechange=function(){
// readyState == 4说明请求已完成
if(xhr.readyState==4){
if(xhr.status==200 || xhr.status==304){
console.log(xhr.responseText);
fn.call(xhr.responseText);
}
}
}
xhr.send();
},
// data应为'a=a1&b=b1'这种字符串格式,在jq里如果data为对象会自动将对象转成这种字符串格式
post: function(url,data,fn){
var xhr=new XMLHttpRequest();
xhr.open('POST',url,false);
// 添加http头,发送信息至服务器时内容编码类型
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.onreadystatechange=function(){
if (xhr.readyState==4){
if (xhr.status==200 || xhr.status==304){
// console.log(xhr.responseText);
fn.call(xhr.responseText);
}
}
}
xhr.send(data);
}
}
一个功能比较全的ajax
//Ajax封装函数
// @params {
// type:'get',
// url:'http://xx/xx',
// data:{name:'aaagu'},
// header:{"Content-type": "application/x-www-form-
// urlencoded"},
// success:function(res){
// },
// failed:function(error){
// }
// }
function Ajax(params){
// 创建ajax对象
var xhr = null;
if(window.XMLHttpRequest){//非IE浏览器
xhr = new XMLHttpRequest();
} else {//IE浏览器
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
//如果服务器没有指定一个Content-Type 头,
//XMLHttpRequest 默认MIME类型为"text/xml".
//如果接受的数据不是有效的XML,
//将会出现格”格式不正确“的错误。
//你能够通过调用 overrideMimeType() 指定各种类型来避免这种情况。
if(params.mimeType){
xhr.overrideMimeType(params.mimeType);
}
xhr.timeout = params.timeout || 10000;
xhr.ontimeout = params.ontimeout;
//一个布尔值,用来指定跨域 Access-Control 请求是否应带有授权信息,如 cookie 或授权 header 头。
xhr.withCredentials = params.withCredentials || false;
//XMLHttpRequest.upload 属性返回一个 XMLHttpRequestUpload对象,用来表示上传的进度。
var upload = xhr.upload;
//获取开始
upload.onloadstart = function(){
console.log('onloadstart');
}
//数据传输进行中
upload.onprogress = function(evt){
console.log('onprogress');
// 进度
if (evt.lengthComputable) {
var pro = Math.round(evt.loaded / evt.total * 100) + "%";
console.log(pro);
}
}
//获取操作终止
upload.onabort = function(){
console.log('onabort');
}
//获取失败
upload.onerror = function(){
console.log('onload');
}
// 获取成功
upload.onload = function(){
console.log('onload');
}
//获取操作在用户规定的时间内未完成
upload.ontimeout = function(){
console.log('ontimeout');
}
//获取完成(不论成功与否)
upload.onloadend = function(){
console.log('onloadend');
}
// 用于清除缓存
var random = Math.random();
var paramsData = '';
if(typeof params.data == 'object'){
var str = '';
for(var key in params.data){
str += key+'='+params.data[key]+'&';
}
paramsData = str.replace(/&$/, '');
}
if(params.type.toUpperCase() == 'GET'){
if(params.data){
xhr.open('GET', params.url + '?' + paramsData, true);
} else {
xhr.open('GET', params.url + '?t=' + random, true);
}
xhr.send();
} else if(params.type.toUpperCase() == 'POST'){
xhr.open('POST', params.url, true);
// 如果需要像 html 表单那样 POST 数据,请使用 setRequestHeader() 来添加 http 头。
if(params.header){
var flag = false;
for(var item in params.header){
if(params.header[item].indexOf('application/json') != -1){
flag = true;
}
xhr.setRequestHeader(item, params.header[item]);
}
if(flag){//如果header 存在application/json 转成字符串
xhr.send(JSON.stringify(params.data));
}else{
xhr.send(params.data);
}
}else{
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(params.data);
}
}
// 处理返回数据
xhr.onreadystatechange = function(){
// xhr.readyState
// 0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 请求处理中 4: 请求已完成,且响应已就绪
if(xhr.readyState == 4){
/*
** xhr.status Http状态码
** 1xx :信息展示 ,2xx :成功 ,3xx :重定向, 4xx : 客户端错误,5xx :服务器端错误
*/
if(xhr.status == 200){
console.log(xhr);
//返回一个 ArrayBuffer、Blob、Document,或 DOMString,具体是哪种类型取决于 XMLHttpRequest.responseType 的值。
//其中包含整个响应体(response body)。
//params.success(xhr.response);
//返回一个 DOMString,该 DOMString 包含对请求的响应,如果请求未成功或尚未发送,则返回 null。
params.success(xhr.responseText);
} else {
if(params.failed){
params.failed(xhr.status);
}
}
}
}
return xhr;
}
var xhr = Ajax({
type:'post',
url:'https://www.example.com/list',
data:{id:1},
header:{"Content-type": "application/json"},
timeout:10000, // 设置请求超时 毫秒
withCredentials:true,
mimeType:'text/plain',
success:function(res){
console.log(res);
console.log(xhr.getAllResponseHeaders())
console.log(xhr.getResponseHeader("Content-type"))
},
failed:function(error){
},
ontimeout:function(timeout){
console.log(timeout)
},
});
状态码:415
image.png
服务器接受的是: application/json, 所以报类型不支持,
状态码:400
image.png
400 错误是请求过去的格式不正确。应该 post请求 xhr.send('{name:'aaagu'}'); 以 json字符串传过去。
失败的情况: 当断网或者请求的url错误的时候,判断超时的回调函数就可以了。