原生h5封装ajax全局挂载(连接失败/请求成功/失败/超时)
// ajax
/**
* 业务 http 请求
* @param uri 接口文档地址, 比如: GET /parkingOrder/{parkingOrderId}/payInfo
* @param input 入参
* @param callback 响应
* @param final 不论成功失败都执行
*/
window.http = function (uri, input,type, callback, final) {
http.loading.startHttp(uri)//旋转加载图标
//入参少了input的时候
if (typeof input === 'function') {
final = callback
callback = input
input = {}
}
var res = ''
var realUri = uri
baseHTTP({
uri: realUri,
input: input,
type:type,
success: function (responce) {
res = responce
},
error: function (http) {
res = {code: http.status, msg: '网络错误 http.status: ' + http.status, http: http}
alert({msg:realUri+'接口出错,请退出重试', callback: window.closeWindow})
},
complete: function () {
http.loading.completeHttp(uri)
callback && callback(res, realUri)
}
})
}
/**
* 底层 http 请求
* @param option 如 defaultOption 所示
*/
function baseHTTP (option) {
var defaultOption = {
uri: '',
input: {},
id: '',
type:'GET',
host: window.config.host,
success: function (res) {}, // 请求成功
error: function (err) {}, // 请求错误
complete: function () {} // 请求完成
}
option = Object.assign(defaultOption, option)
var http = new XMLHttpRequest()
http.onreadystatechange = function () {
if (http.readyState === 4) {
if (http.status === 200) {
var result = JSON.parse(http.responseText)
option.success(result)
} else {
option.error(http)
}
option.complete(http)
}
}
var type = option.type?option.type:'GET'//ny 判断get/post \s匹配任何空白字符 [^\s]匹配任何非空白字符
var url = option.host + option.uri//id 在上一步已近被替换了,在这应该用不到了
if (type === 'GET') {
var getParam = '?'
option.input && Object.keys(option.input).forEach(function (key) {
var item = option.input[key]
if (item && typeof item === 'object') {
getParam += key + '=' + JSON.stringify(item) + '&'
} else {
getParam += key + '=' + (item || '') + '&'
}
})
//将最后一个&结尾字符去掉
url += getParam.replace(/[&|?]$/, '')
}
if(type === 'POST'){
}
//处理当open之前--->readyState=4 之前发生的错误
http.onerror = function(){
// 处理连接级别的错误
option.error(http)
return
};
console.log(type,url)
http.open(type, url, true)
http.setRequestHeader('Content-type', 'application/json')
localStorage.sessionId && http.setRequestHeader('sessionId', localStorage.sessionId)
//超过7秒视为超时
http.timeout = 7000
http.ontimeout=function(){
alert({msg: option.uri+'接口'+objs.type+',请退出重试', callback: window.closeWindow})
}
http.send(JSON.stringify(option.input))
}
/** 如果请求时间超过 1 秒钟还没响应, 那么自动 loading **/
http.loading = {
timeout: 1000,
timeoutList: {},
startHttp: function (uri) {
clearTimeout(this.timeoutList[uri]) // TODO 同一个请求在没有响应的时候又发起了, 那么这时有漏洞
this.timeoutList[uri] = setTimeout(this.show, this.timeout)
},
completeHttp: function (uri) {
//判断是否存在接口超时的情况 如果有就提示,跳出弹框 关闭页面
clearTimeout(this.timeoutList[uri])
this.timeoutList[uri] = undefined
this.hide()
},
show: function () {
if (document.body.className.indexOf('http-loading') > -1) return
$(document.body).addClass('http-loading')
},
hide: function () {
var isOk = true // 可以隐藏
var t = this
//这里用forEach 不好 用some 之类的可能会好(兼容?)
Object.keys(t.timeoutList).forEach(function (key) {
var item = t[key]
if (item !== undefined) {
isOk = false
}
})
if (!isOk) return
$(document.body).removeClass('http-loading')
}
}
页面用法:
http('/goods', {
example:'测试',
},'GET', function (res, uri) {
console.log('打印结果',res)
})