class HttpRequest {
baseUrl = null
interceptors = {
request: [],
response: [],
}
constructor(baseUrl = '') {
this.baseUrl = baseUrl
this.interceptors = {
request: [],
response: [],
}
}
use(type, interceptor) {
if (type === 'request' || type === 'response') {
this.interceptors[type].push(interceptor)
}
}
async get(url, params = {}, headers = {}) {
return this._sendRequest('GET', url, params, headers)
}
async post(url, data = {}, headers = {}) {
return this._sendRequest('POST', url, data, headers)
}
async put(url, data = {}, headers = {}) {
return this._sendRequest('PUT', url, data, headers)
}
async delete(url, params = {}, headers = {}) {
return this._sendRequest('DELETE', url, params, headers)
}
async _sendRequest(method, url, data = null, headers = {}) {
let finalUrl = this.baseUrl + url
const finalMethod = method.toUpperCase()
let finalHeaders = { 'Content-Type': 'application/json', ...headers }
let finalData = data
// 应用请求拦截器
for (const interceptor of this.interceptors.request) {
const result = await interceptor({ method: finalMethod, url: finalUrl, data: finalData, headers: finalHeaders })
finalUrl = result.url
finalData = result.data
finalHeaders = result.headers
}
if (finalMethod === 'GET' || finalMethod === 'DELETE') {
const params = new URLSearchParams(finalData).toString()
finalUrl += params ? `?${params}` : ''
finalData = null
}
else {
finalData = JSON.stringify(finalData)
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open(finalMethod, finalUrl, true)
for (const key in finalHeaders) {
if (Object.prototype.hasOwnProperty.call(finalHeaders, key)) {
xhr.setRequestHeader(key, finalHeaders[key])
}
}
xhr.onload = async () => { // 使用箭头函数来保持正确的 this 上下文
let responseData
try {
responseData = JSON.parse(xhr.responseText)
}
catch (error) {
responseData = xhr.responseText
}
let response = {
data: responseData,
status: xhr.status,
statusText: xhr.statusText,
headers: xhr.getAllResponseHeaders(),
}
// 应用响应拦截器
for (const interceptor of this.interceptors.response) {
try {
response = await interceptor(response)
}
catch (error) {
reject(error)
return
}
}
if (xhr.status >= 200 && xhr.status < 300) {
resolve(response.data)
}
else {
reject(new Error(`HTTP error! status: ${xhr.status}`))
}
}
xhr.onerror = () => { // 同样使用箭头函数
reject(new Error('Network error occurred'))
}
xhr.send(finalData)
})
}
}
export default HttpRequest
使用TypeScript封装XMLHttpRequest
发表于: 2024-08-04 21:15:49
简介: 使用TypeScript对XMLHttpRequest进行封装,类似axios库
最后更新于:2024-08-04 21:15:49