/*
使用promise 封装XMLHttpRequest
(resove, reject) 对应请求的(then,catch)
config 请求参数
data 可选
url 必须
method 必须
timetout 可选默认(3000)
responseType 可选
使用时,then先后catch
*/
export default function xhrRequest (config) {
return new Promise(function dispRequest (resolve, reject) {
if (!config.url) {
return reject(createError('请求的URL不存在', config, null))
}
if (!config.method) {
return reject(createError('请求方式不存在', config, null))
}
// form data
var requestData = new FormData()
var data = config.data
for (const key in data) {
requestData.append(key, data[key])
}
// var requestData = new FormData(config.data)
var request = new XMLHttpRequest()
var URL = config.url
var method = config.method.toUpperCase()
request.open(method, URL, true)
request.timeout = config.timetout || 3000
// listen for ready state
request.onreadystatechange = function () {
if (!request || request.readyState !== 4) {
return
}
if (
request.status === 0 &&
!(request.reponseURL && request.reponseURL.indexof('file') === 0)
) {
return
}
// 进度
request.upload.onprogress = function (a, b) {
console.log(a, b)
}
// 浏览器取消
request.onabort = function () {
if (!request) {
return
}
reject(createError('请求取消', config, 'ECONNABORTED', request))
request = null
}
// 网络错误
request.onerror = function () {
reject(createError('网络错误', config, null, request))
request = null
}
// timeout
request.ontimeout = function () {
var timeoutErrorMessage = '请求超时 ' + config.timeout + 'ms exceeded'
if (config.timeoutErrorMessage) {
timeoutErrorMessage = config.timeoutErrorMessage
}
reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', request))
request = null
}
// request.status 可能的状态码
// 404
// 200
// 500
const state = request.status
const stateString = {
404: '请求的网页不存在!',
500: '服务不可用!'
}
if (state === 404 || state === 500) {
reject(createError('请求错误,类型:' + stateString[state] + '多次出现请联系管理员', config, null, request))
request = null
return
}
var responseHeaders =
'getAllResponseHeaders' in request
? parseHeaders(request.getAllResponseHeaders())
: null
var responseData = !config.responseType || config.responseType === 'text'
? request.responseText
: request.response
var response = {
data: JSON.parse(responseData),
status: request.status,
statusText: request.statusText,
headers: responseHeaders,
config: config,
request: request
}
settle(resolve, reject, response)
// Clean up request
request = null
}
if (requestData === undefined) {
requestData = null
}
// Send the request
request.send(requestData)
})
}
function settle (resolve, reject, response) {
var validateStatus = response.config.validateStatus
if (!validateStatus || validateStatus(response.status)) {
resolve(response)
} else {
reject(
createError(
'请求异常,状态码为:' + response.status,
response.config,
null,
response.request,
response
)
)
}
}
function createError (message, config, code, request, response) {
var error = { error: message }
return enhanceError(error, config, code, request, response)
}
function enhanceError (error, config, code, request, response) {
error.config = config
if (code) {
error.code = code
}
error.request = request
error.response = response
error.isAxiosError = true
error.toJSON = function () {
return {
// Standard
message: this.message,
name: this.name,
// Microsoft
description: this.description,
number: this.number,
// Mozilla
fileName: this.fileName,
lineNumber: this.lineNumber,
columnNumber: this.columnNumber,
stack: this.stack,
// Axios
config: this.config,
code: this.code
}
}
return error
}
function parseHeaders (headers) {
var obj = {}
var arr = headers.split(/[(\r\n)\r\n]+/)
arr.pop()
arr.forEach(item => {
// item = item.concat('"').replace(/: /g, ': "')
var rp = item.split(':', 2)
obj[rp[0]] = rp[1].substr(1)
})
return obj
}
使用示例
const config = {
url: url,
method: 'post',
data: { name, password }
}
Request(config)
.then((res) => {
console.log(res)
this.$message(res.data ? res.data.msg : '数据异常')
})
.catch((err) => {
console.log(err)
this.$message(err.error)
})