puzzle/src/frontend/xhr.ts
2021-06-20 13:40:28 +02:00

56 lines
1.5 KiB
TypeScript

export interface Response {
status: number,
text: string,
json: () => Promise<any>,
}
export interface Options {
body: FormData|string,
headers?: any,
onUploadProgress?: (ev: ProgressEvent<XMLHttpRequestEventTarget>) => any,
}
const request = async (
method: string,
url: string,
options: Options
): Promise<Response> => {
return new Promise((resolve, reject) => {
const xhr = new window.XMLHttpRequest()
xhr.open(method, url, true)
xhr.withCredentials = true
for (const k in options.headers || {}) {
xhr.setRequestHeader(k, options.headers[k])
}
xhr.addEventListener('load', function (ev: ProgressEvent<XMLHttpRequestEventTarget>
) {
resolve({
status: this.status,
text: this.responseText,
json: async () => JSON.parse(this.responseText),
})
})
xhr.addEventListener('error', function (ev: ProgressEvent<XMLHttpRequestEventTarget>) {
reject(new Error('xhr error'))
})
if (xhr.upload && options.onUploadProgress) {
xhr.upload.addEventListener('progress', function (ev: ProgressEvent<XMLHttpRequestEventTarget>) {
// typescript complains without this extra check
if (options.onUploadProgress) {
options.onUploadProgress(ev)
}
})
}
xhr.send(options.body)
})
}
export default {
request,
get: (url: string, options: any): Promise<Response> => {
return request('get', url, options)
},
post: (url: string, options: any): Promise<Response> => {
return request('post', url, options)
},
}