| 226 | * @return {Promise<VMReq.Response>} |
| 227 | */ |
| 228 | export async function requestLocalFile(url, options = {}) { |
| 229 | // only GET method is allowed for local files |
| 230 | // headers is meaningless |
| 231 | return new Promise((resolve, reject) => { |
| 232 | const xhr = new XMLHttpRequest(); |
| 233 | /** @type {VMReq.Response} */ |
| 234 | const result = { |
| 235 | headers: { |
| 236 | get: name => xhr.getResponseHeader(name), |
| 237 | }, |
| 238 | url, |
| 239 | }; |
| 240 | const { [kResponseType]: responseType } = options; |
| 241 | xhr.open('GET', url, true); |
| 242 | if (binaryTypes.includes(responseType)) xhr[kResponseType] = responseType; |
| 243 | xhr.onload = () => { |
| 244 | // status for `file:` protocol will always be `0` |
| 245 | result.status = xhr.status || 200; |
| 246 | result.data = xhr[binaryTypes.includes(responseType) ? kResponse : kResponseText]; |
| 247 | if (responseType === 'json') { |
| 248 | try { |
| 249 | result.data = JSON.parse(result.data); |
| 250 | } catch { |
| 251 | // ignore invalid JSON |
| 252 | } |
| 253 | } |
| 254 | resolve(result); |
| 255 | }; |
| 256 | xhr.onerror = () => { |
| 257 | result.status = -1; |
| 258 | reject(result); |
| 259 | }; |
| 260 | xhr.send(); |
| 261 | }); |
| 262 | } |
| 263 | |
| 264 | const isDataUriRe = /^data:/i; |
| 265 | const isHttpOrHttpsRe = /^https?:\/\//i; |