137 lines
3.4 KiB
JavaScript
Raw Normal View History

import EventTarget from './EventTarget.js'
const _url = new WeakMap()
const _method = new WeakMap()
const _requestHeader = new WeakMap()
const _responseHeader = new WeakMap()
const _requestTask = new WeakMap()
function _triggerEvent(type, ...args) {
if (typeof this[`on${type}`] === 'function') {
this[`on${type}`].apply(this, args)
}
}
function _changeReadyState(readyState) {
this.readyState = readyState
_triggerEvent.call(this, 'readystatechange')
}
export default class XMLHttpRequest extends EventTarget {
// TODO 没法模拟 HEADERS_RECEIVED 和 LOADING 两个状态
static UNSEND = 0
static OPENED = 1
static HEADERS_RECEIVED = 2
static LOADING = 3
static DONE = 4
timeout = 0;
/*
* TODO 这一批事件应该是在 XMLHttpRequestEventTarget.prototype 上面的
*/
onabort = null
onerror = null
onload = null
onloadstart = null
onprogress = null
ontimeout = null
onloadend = null
onreadystatechange = null
readyState = 0
response = null
responseText = null
responseType = ''
responseXML = null
status = 0
statusText = ''
upload = {}
withCredentials = false
constructor() {
super();
_requestHeader.set(this, {
'content-type': 'application/json'
})
_responseHeader.set(this, {})
}
abort() {
const myRequestTask = _requestTask.get(this)
if (myRequestTask) {
myRequestTask.abort()
}
}
getAllResponseHeaders() {
const responseHeader = _responseHeader.get(this)
return Object.keys(responseHeader).map((header) => {
return `${header}: ${responseHeader[header]}`
}).join('\n')
}
getResponseHeader(header) {
return _responseHeader.get(this)[header]
}
open(method, url/* async, user, password 这几个参数在小程序内不支持*/) {
_method.set(this, method)
_url.set(this, url)
_changeReadyState.call(this, XMLHttpRequest.OPENED)
}
overrideMimeType() {
}
send(data = '') {
if (this.readyState !== XMLHttpRequest.OPENED) {
throw new Error("Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.")
} else {
let myRequestTask = my.tb.request({
body: JSON.stringify(data),
url: _url.get(this),
method: _method.get(this),
headers: _requestHeader.get(this),
options: {timeout: this.timeout, enableSystemParams: true},
success: (res) => {
this.status = res.code;
this.responseText = this.response = res.content;
_responseHeader.set(this, _requestHeader.get(this))
_triggerEvent.call(this, 'loadstart')
_changeReadyState.call(this, XMLHttpRequest.HEADERS_RECEIVED)
_changeReadyState.call(this, XMLHttpRequest.LOADING)
_changeReadyState.call(this, XMLHttpRequest.DONE)
_triggerEvent.call(this, 'load')
_triggerEvent.call(this, 'loadend')
},
fail: (res) => {
_triggerEvent.call(this, 'error', res)
_triggerEvent.call(this, 'loadend')
}
})
_requestTask.set(this, myRequestTask);
}
}
setRequestHeader(header, value) {
const myHeader = _requestHeader.get(this)
myHeader[header] = value
_requestHeader.set(this, myHeader)
}
addEventListener(type, listener) {
if (typeof listener === 'function') {
let _this = this
let event = { target: _this }
this['on' + type] = function (event) {
listener.call(_this, event)
}
}
}
}