* * * @param {string} input * @param {!FetchInitDef} init * @return {!Promise<!{response: !Response, xhr: !XMLHttpRequest}>} * @private
(input, init)
| 52 | * @private |
| 53 | */ |
| 54 | function xhrRequest(input, init) { |
| 55 | return new Promise((resolve, reject) => { |
| 56 | const xhr = new XMLHttpRequest(); |
| 57 | xhr.open(init.method || 'GET', input, true); |
| 58 | xhr.withCredentials = init.credentials == 'include'; |
| 59 | xhr.responseType = 'document'; |
| 60 | // Incoming headers are in fetch format, |
| 61 | // so we need to convert them into xhr. |
| 62 | for (const header in init.headers) { |
| 63 | xhr.setRequestHeader(header, init.headers[header]); |
| 64 | } |
| 65 | |
| 66 | xhr.onreadystatechange = () => { |
| 67 | if (xhr.readyState < /* STATUS_RECEIVED */ 2) { |
| 68 | return; |
| 69 | } |
| 70 | if (xhr.status < 100 || xhr.status > 599) { |
| 71 | xhr.onreadystatechange = null; |
| 72 | reject(user().createExpectedError(`Unknown HTTP status ${xhr.status}`)); |
| 73 | return; |
| 74 | } |
| 75 | // TODO(dvoytenko): This is currently simplified: we will wait for the |
| 76 | // whole document loading to complete. This is fine for the use cases |
| 77 | // we have now, but may need to be reimplemented later. |
| 78 | if (xhr.readyState == /* COMPLETE */ 4) { |
| 79 | const options = { |
| 80 | status: xhr.status, |
| 81 | statusText: xhr.statusText, |
| 82 | headers: parseHeaders(xhr.getAllResponseHeaders()), |
| 83 | }; |
| 84 | const response = new Response( |
| 85 | '', |
| 86 | /** @type {!ResponseInit} */ (options) |
| 87 | ); |
| 88 | const promise = assertSuccess(response).then((response) => ({ |
| 89 | response, |
| 90 | xhr, |
| 91 | })); |
| 92 | resolve(promise); |
| 93 | } |
| 94 | }; |
| 95 | xhr.onerror = () => { |
| 96 | reject(user().createExpectedError('Request failure')); |
| 97 | }; |
| 98 | xhr.onabort = () => { |
| 99 | reject(user().createExpectedError('Request aborted')); |
| 100 | }; |
| 101 | if (init.method == 'POST') { |
| 102 | xhr.send(/** @type {!FormData} */ (init.body)); |
| 103 | } else { |
| 104 | xhr.send(); |
| 105 | } |
| 106 | }); |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Parses XHR's response headers into JSONObject. |
no test coverage detected