前端http请求和常见的⼏个请求技术做具体的讲解
对于前端来说,请求是前端⽇常⼯作必备的,通过请求才能与后端进⾏数据交互,尤其在现在前后端分离的开发模式下,请求显得就更加重要。因此,对于前端开发者来说,掌握请求就很重要。下⾯将从http请求和常见的⼏个请求技术做具体的讲解
⼀、XMLHttpRequest
XMLHttpRequest⼀开始只是微软浏览器提供的⼀个接⼝,后来各⼤浏览器纷纷效仿也提供了这个接⼝,再后来W3C对它进⾏了标准化,按照标准前后可以分为两个版本,具体阐述如下:
版本以(⽼版本):
//新建⼀个XMLHttpRequest对象
var xhr=new XMLHttpRequest();
//进⾏请求
xhr.open('GET', 'url');
xhr.send();
//等待服务器响应
//该函数会被调⽤四次,因此需要判断状态是否为4
if ( adyState == 4 && xhr.status == 200 ) {
alert( sponseText );
} else {
alert( xhr.statusText );
}
};
在⽼版本中的,对应的具体属性说明如下:
1. adyState:XMLHttpRequest对象的状态,等于4表⽰数据已经接收完毕。
2. xhr.status:服务器返回的状态码,等于200表⽰⼀切正常。
3. sponseText:服务器返回的⽂本数据
4. sponseXML:服务器返回的XML格式的数据
5. xhr.statusText:服务器返回的状态⽂本。
⽼版本因为不是统⼀的标准,各个浏览器⼚商在实现的时候都有⼀定的差异,⽽且在存在⼀些缺陷:
1. 只⽀持⽂本数据的传送,⽆法⽤来读取和上传⼆进制⽂件。
2. 传送和接收数据时,没有进度信息,只能提⽰有没有完成。
3. 受到"同域限制"(Same Origin Policy),只能向同⼀域名的服务器请求数据。
版本⼆(标准后的版本):
为了更好的使⽤XMLHttpRequest,w3school发布了标准版本,该版本弥补了版本⼀的缺陷,也被各⼤浏览器⼚商接受并实现。具体为:
1. 可以设置HTTP请求的时限。
2. 可以使⽤FormData对象管理表单数据。
3. 可以上传⽂件。
4. 可以请求不同域名下的数据(跨域请求)。
5. 可以获取服务器端的⼆进制数据。
6. 可以获得数据传输的进度信息。
当然,⼀般为了友好的进⾏兼容各个浏览器,会采⽤对浏览器进⾏判断并进⾏兼容性模式来获取XMLHttpRequest的对象
var xhr;
if (window.XMLHttpRequest) { // Mozilla,
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP'); //IE5,6
} catch (e) {}
}
}
// 请求成功回调函数
console.log('request success');
};
// 请求结束
console.log('request loadend');
};
// 请求出错
console.log('request error');
};
// 请求超时
console.log('request timeout');
};
// 请求回调函数.XMLHttpRequest标准⼜分为Level 1和Level 2,这是Level 1和的回调处理⽅式
// adystatechange = () => {
// if (adyState !== 4) {
// return;
// }
// const status = xhr.status;
// if ((status >= 200 && status < 300) || status === 304) {
// console.log('request success');
// } else {
/
/ console.log('request error');
// }
// };
xhr.timeout = 0; // 设置超时时间,0表⽰永不超时
// 初始化请求
xhr.open('GET/POST/DELETE/...', '/url', true || false);
// 设置期望的返回数据类型 'json' 'text' 'document' ...
// 设置请求头
xhr.setRequestHeader('', '');
// 发送请求
xhr.send(null || new FormData || 'a=1&b=2' || 'json字符串');
⼆、ajax请求
AJAX 是⼀种与服务器交换数据的技术,可以在不重新载⼊整个页⾯的情况下更新⽹页的⼀部分,其实就是对XMLHttpRequest的封装,可以直接引⼊jquery⼯具包来进⾏调⽤ajax请求(jquery是⼀个js⼯具包,其特点是:写得少,做得多),具体的ajax常⽤⽅式如下:⽅法描述
$.ajax()执⾏异步 AJAX 请求
$.ajaxPrefilter()在每个请求发送之前且被 $.ajax() 处理之前,处理⾃定义 Ajax 选项或修改已存在选项
$.ajaxSetup()为将来的 AJAX 请求设置默认值
$.ajaxTransport()创建处理 Ajax 数据实际传送的对象
$.get()使⽤ AJAX 的 HTTP GET 请求从服务器加载数据
$.getJSON()使⽤ HTTP GET 请求从服务器加载 JSON 编码的数据
$.getScript()使⽤ AJAX 的 HTTP GET 请求从服务器加载并执⾏ JavaScript
$.param()创建数组或对象的序列化表⽰形式(可⽤于 AJAX 请求的 URL 查询字符串)
$.post()使⽤ AJAX 的 HTTP POST 请求从服务器加载数据
ajaxComplete()规定 AJAX 请求完成时运⾏的函数
ajaxError()规定 AJAX 请求失败时运⾏的函数
ajaxSend()规定 AJAX 请求发送之前运⾏的函数
ajaxStart()规定第⼀个 AJAX 请求开始时运⾏的函数
ajaxStop()规定所有的 AJAX 请求完成时运⾏的函数
ajaxSuccess()规定 AJAX 请求成功完成时运⾏的函数
load()从服务器加载数据,并把返回的数据放置到指定的元素中
serialize()编码表单元素集为字符串以便提交
serializeArray()编码表单元素集为 names 和 values 的数组
优点:
对原⽣XHR的封装
针对MVC的编程
完美的兼容性
⽀持jsonp
缺点:
不符合MVVM
异步模型不够现代,不⽀持链式,代码可读性差
整个Jquery太⼤,引⼊成本过⾼
当然,我们可以直接使⽤XMLHttpReqeust来进⾏实现⾃⼰的ajax封装,具体代码如下:
const http = {
/
**
* js封装ajax请求
* >>使⽤new XMLHttpRequest 创建请求对象,所以不考虑低端IE浏览器(IE6及以下不⽀持XMLHttpRequest)
* >>使⽤es6语法,如果需要在正式环境使⽤,则可以⽤babel转换为es5语法 babeljs/docs/setup/#installation
* @param settings 请求参数模仿jQuery ajax
* 调⽤该⽅法,data参数需要和请求头Content-Type对应
* Content-Type data 描述
* application/x-www-form-urlencoded 'name=哈哈&age=12'或{name:'哈哈',age:12} 查询字符串,⽤&分割
* application/json name=哈哈&age=12' json字符串
* multipart/form-data new FormData() FormData对象,当为FormData类型,不要⼿动设置Content-Type * 注意:请求参数如果包含⽇期类型.是否能请求成功需要后台接⼝配合
*/
ajax: (settings = {}) => {
// 初始化请求参数
let _s = Object.assign({
url: '', // string
type: 'GET', // string 'GET' 'POST' 'DELETE'
dataType: 'json', // string 期望的返回数据类型:'json' 'text' 'document' ...
async: true, // boolean true:异步请求 false:同步请求 required
data: null, // any 请求参数,data需要和请求头Content-Type对应
headers: {}, // object 请求头
timeout: 1000, // string 超时时间:0表⽰不设置超时
beforeSend: (xhr) => {
},
success: (result, status, xhr) => {
},
error: (xhr, status, error) => {
},
complete: (xhr, status) => {
}
}, settings);
/
/ 参数验证
if (!_s.url || !_s.type || !_s.dataType || !_s.async) {
alert('参数有误');
return;
}
// 创建XMLHttpRequest请求对象
let xhr = new XMLHttpRequest();
// 请求开始回调函数
xhr.addEventListener('loadstart', e => {
_s.beforeSend(xhr);
});
/
/ 请求成功回调函数
xhr.addEventListener('load', e => {
const status = xhr.status;
if ((status >= 200 && status < 300) || status === 304) {
let result;
if (sponseType === 'text') {
result = sponseText;ajax实例 文件浏览
} else if (sponseType === 'document') {
result = sponseXML;
} else {
result = sponse;
}
// 注意:状态码200表⽰请求发送/接受成功,不表⽰业务处理成功
_s.success(result, status, xhr);
} else {
_s.error(xhr, status, e);
}
});
// 请求结束
xhr.addEventListener('loadend', e => {
_splete(xhr, xhr.status);
});
/
/ 请求出错
xhr.addEventListener('error', e => {
_s.error(xhr, xhr.status, e);
});
// 请求超时
xhr.addEventListener('timeout', e => {
_s.error(xhr, 408, e);
});
let useUrlParam = false;
let sType = _UpperCase();
// 如果是"简单"请求,则把data参数组装在url上
if (sType === 'GET' || sType === 'DELETE') {
useUrlParam = true;
_s.url += UrlParam(_s.url, _s.data);
}
// 初始化请求
xhr.open(_s.type, _s.url, _s.async);
// 设置期望的返回数据类型
// 设置请求头
for (const key of Object.keys(_s.headers)) {
xhr.setRequestHeader(key, _s.headers[key]);
}
// 设置超时时间
if (_s.async && _s.timeout) {
xhr.timeout = _s.timeout;
}
// 发送请求.如果是简单请求,请求参数应为null.否则,请求参数类型需要和请求头Content-Type对应
xhr.send(useUrlParam ? null : QueryData(_s.data));
},
// 把参数data转为url查询参数
getUrlParam: (url, data) => {
if (!data) {
return '';
}
let paramsStr = data instanceof Object ? QueryString(data) : data;
return (url.indexOf('?') !== -1) ? paramsStr : '?' + paramsStr;
},
// 获取ajax请求参数
getQueryData: (data) => {
if (!data) {
return null;
}
if (typeof data === 'string') {
return data;
}
if (data instanceof FormData) {
return data;
}
QueryString(data);
},
// 把对象转为查询字符串
getQueryString: (data) => {
let paramsArr = [];
if (data instanceof Object) {
Object.keys(data).forEach(key => {
let val = data[key];
// todo 参数Date类型需要根据后台api酌情处理
if (val instanceof Date) {
// val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss');
}
paramsArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
});
}
return paramsArr.join('&');
}
}
三、vue-resource请求
vue-resource是Vue.js的⼀款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件⼀样也能做到,⽽且vue-resource的API更为简洁。另外,vue-resource还提供了⾮常有⽤的inteceptor功能,使⽤inteceptor可以在请求前和请求后附加⼀些⾏为,⽐如使⽤inteceptor在ajax请求时显⽰loading界⾯。
特点
1. 体积⼩
vue-resource⾮常⼩巧,在压缩以后只有⼤约12KB,服务端启⽤gzip压缩后只有4.5KB⼤⼩,这远⽐jQuery的体积要⼩得多。
2. ⽀持主流的浏览器
和Vue.js⼀样,vue-resource除了不⽀持IE 9以下的浏览器,其他主流的浏览器都⽀持。
3. ⽀持Promise API和URI Templates
Promise是ES6的特性,Promise的中⽂含义为“先知”,Promise对象⽤于异步计算。
URI Templates表⽰URI模板,有些类似于ASP.NET MVC的路由模板。
4. ⽀持
是全局的,可以在请求发送前和发送请求后做⼀些处理。
在⼀些场景下会⾮常有⽤,⽐如请求发送前在headers中设置access_token,或者在请求失败时,提供共通的处理⽅式。
常⽤api
1. get(url, [options])
2. head(url, [options])
3. delete(url, [options])
4. jsonp(url, [options])
5. post(url, [body], [options])
6. put(url, [body], [options])
7. patch(url, [body], [options])
客户端请求⽅法服务端处理⽅法
this.$(...)Getxxx
this.$http.post(...)Postxxx
this.$http.put(...)Putxxx
this.$http.delete(...)Deletexxx
option详解
参数类型描述
url string请求的URL
method string请求的HTTP⽅法,例如:'GET', 'POST'或其他HTTP⽅法
body Object, FormData
string
request body
params Object请求的URL参数对象
headers Object request header
timeout number单位为毫秒的请求超时时间 (0 表⽰⽆超时时间)
before function(request)请求发送前的处理函数,类似于jQuery的beforeSend函数
progress function(event)ProgressEvent回调处理函数
credentials boolean表⽰跨域请求时是否需要使⽤凭证
emulateHTTP boolean发送PUT, PATCH, DELETE请求时以HTTP POST的⽅式发送,并设置请求头的X-HTTP-Method-
Override
emulateJSON boolean将request body以application/x-www-form-urlencoded content type发送
四、fetch
1. fetch是基于promise实现的,也可以结合async/await
2. fetch请求默认是不带cookie的,需要设置fetch(URL,{credentials:’include’})。
3. Credentials有三种参数:same-origin,include,*
4. 服务器返回400 500 状态码时并不会reject,只有⽹络出错导致请求不能完成时,fetch才会被reject
5. 所有版本的 IE 均不⽀持原⽣ Fetch
6. fetch是widow的⼀个⽅法
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
可配合es6的箭头函数进⾏使⽤
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
五、axios
Axios 是⼀个基于 promise 的 HTTP 库,可以⽤在浏览器和 node.js 中
特点
从浏览器中创建XMLHttpRequests
从 node.js 创建http请求
⽀持PromiseAPI
拦截请求和响应
转换请求数据和响应数据
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论