AJAX
异步的JavaScript与XML技术( Asynchronous JavaScript and XML )
Ajax 核心使用 `XMLHttpRequest` (XHR)对象,首先由微软引入的一个特性;Ajax 不需要任何浏览器插件,能在不更新整个页面的前提下维护数据(可以向服务器请求额外的数据无需重载页面,但需要用户允许JavaScript在浏览器上执行。
XHR 对象用法
var xhr = new XMLRequestHttp() // 通过XMLHttpRequest 构造函数来创建
open 方法
xhr.open(method, url, async, user, password);
method:要发送的请求类型 GET、POST、PUT、DELETE 。(必选)
url:请求的URL (必选)
axync :布尔值,是否异步发送请求,默认true(true 时,已完成事务的通知可供事件监听使用,如果 xhr.multipart为true,则此参数必须为true;false 时,send()方法直到收到答复前不会返回)
user:用户名用于认证用途 默认 null
password:用户名用于认证用途 默认 null
调用open方法不会真正发送请求,只是准备发送请求,并且URL有同源策略的限制(须和页面的主域、端口、协议一致,只要一处不符合要求将报错,数据将被拦截,可通过前后端配置,或使用代理来解决)。
setRequestHeader()
如需设置 Accpet 头部信息,可通过setRequestHeader() 方法来设置
Accpet 头部信息:告知客户端可以处理的内容类型,用 MIME类型 表示;使用 Content-Type 服务端使用 `Content-Type` 通知客户端它的选择
媒体类型( MIME类型 ) :一种标准,用来表示文档、文件或字节流的性质和格式。 完整类型列表
Content-Type :实体头部用于指示资源的 MIME 类型,告诉客户端实际返回的内容类型;浏览器会在某些情况下进行MIME查找,并不一定遵循此标题的值; 为了防止这种行为,可以将标题 X-Content-Type-Options 设置为 nosniff。
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
send 方法
xhr.send(data);
data:作为请求主体发送的数据,如果不需要通过请求主体发送数据,则必须传 null
调用 send()发送请求,在收到响应后,响应的数据会自动填充XHR对象的属性
responseText :从服务端返回的文本
xhr.onload = function () {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200) { console.log(xhr.responseText);
}
}
};
status
返回响应的HTTP状态码,请求完成前值为0,如果XHR 对象出错 值也是0, 200 表示请求成功,304表示请求的资源并没有修改,可直接使用浏览器种缓存的数据。 其它状态信息
statusText
返回响应的HTTP状态说明,status 值为 200 时 statusText为 "OK"
readyState
返回一个当前XHR对象所处的活动状态
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT | 代理被创建,但尚未调用 open() 方法。 |
1 | OPENED | open() 方法已经被调用。 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且头部和状态已经可获得。 |
3 | LOADING | 下载中;响应体部分正在被接收 responseText 属性已经包含部分数据。 |
4 | DONE | 下载操作已完成。 |
onreadystatechange
当 readyState变化时会触发次事件函数,如果使用 abort() 取消请求则次事件函数不会被触发
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText)
}
}
二次封装全部代码
function baseAjax(options){
let that = this
let setting = {
//地址
url:'',
//请求参数
data: {},
//请求类型
method:'get',
//是否异步请求 默认异步请求
async: 'true',
//请求头信息
headers: {},
//是否发送跨域凭证
withCredentials: false,
//超时时间
timeout: 5000,
//返回类型
dataType:'json',
//成功回调
success: null,
//错误回调
error:null,
//返回请求结果
complete: null
}
options = yicheUtils.extend(options,setting)
//初始化请求对象
let xhr = null
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
try {
xhr = new XDomainRequest("Msxml2.XMLHTTP");
} catch (e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
}
var timer = 0
//超时处理机制
if(options.timeout)
{
timer = setTimeout(function (){
options.error && options.error(xhr);
options.complete && options.complete(xhr,"timeout");
xhr.onreadystatechange = null;
//停止当前请求
xhr.abort()
}, options.timeout);
}
//4.请求接收回调
xhr.onreadystatechange = function (){
let status = ''
//完成
if(xhr.readyState == 4)
{
//成功
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304)
{
status = 'success'
options.success && options.success(resultData(xhr,options));
}
else
{
status = 'error'
options.error && options.error('');
}
options.complete && options.complete(xhr, status);
clearTimeout(timer);
}
}
if(options.method.toLowerCase() == 'get'){
//返回请求参数
let sData = getParam(options.data)
//打开请求
xhr.open('get', options.url + (sData ? '?' + sData : ""), options.async == 'true');
//循环遍历添加请求头
for(let h in options.headers){
xhr.setRequestHeader(h, options.headers[h]);
}
//设置是否发送跨域凭证
xhr.withCredentials = options.xhrFields.withCredentials
//发送请求
xhr.send();
}else{
//打开请求
xhr.open('post', options.url, options.async == 'true');
//循环遍历添加请求头
for(let h in options.headers){
xhr.setRequestHeader(h, options.headers[h]);
}
//设置是否发送跨域凭证
xhr.withCredentials = options.xhrFields.withCredentials
//发送请求
xhr.send(options.data);
}
}
/*************************附加方法 start************************ */
/**
* 返回请求参数
* @param data {object} 请求参数对象
* return {array}
*/
function getParam(data){
let arr = []
for(let i in data){
arr.push(i+'=' + encodeURIComponent(data[i]));
}
return arr.join('&');
}
/**
* 结构转换
* @param xhr {object} 请求类
* @param options {json} 配置参数
* return {object} 返回结果
*/
function resultData (xhr, options) {
let json = {}
if(options.dataType == 'json'){
try{
json = JSON.parse(xhr.responseText)
}catch(e){
json = {}
console.error("请求接口返回值格式异常:",e)
}
}
if(options.dataType == 'blob'){
json = xhr.response
}
return json
}
/*************************附加方法 end************************ */
兼容性
希望以上代码能给大家带来帮助