Created
September 17, 2020 13:37
-
-
Save asaaki/7f9117329332cc910449dd4968f300e5 to your computer and use it in GitHub Desktop.
fetch and no-cors, a difficult story
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fetch - readable on origin only (it does make the call though) | |
let res = await (async () => { | |
const url = "https://markentier.tech/feed.json"; | |
// const url = "https://dummy.restapiexample.com/api/v1/employee/9"; | |
const res = await fetch(url, { mode: "no-cors" }); | |
if(res.ok && res.status === 200) { | |
const body = await res.json(); | |
return {body} | |
// const headers = Object.fromEntries(res.headers); | |
// return { body, headers } | |
} | |
return { error: "nope", res } | |
})() | |
res // Response type=opaque | |
// no body or anything useful 😭 | |
// XHR - works everywhere - yay! | |
const xhrFetch = (() => { | |
const splitOnce = (input, delim = ": ") => { | |
const parts = input.split(delim); | |
const left = parts.shift(); | |
const right = parts.join(delim); | |
return [left, right]; | |
}; | |
const headerMap = (headerArray, init = {}) => { | |
return headerArray.reduce((acc, line) => { | |
const [header, value] = splitOnce(line, ": "); | |
acc[header] = value; | |
return acc; | |
}, init); | |
}; | |
return async (url, overrideMimeType = "application/json") => { | |
return new Promise((resolve, reject) => { | |
const xhr = new XMLHttpRequest(); | |
xhr.overrideMimeType(overrideMimeType); | |
xhr.onload = () => { | |
if (xhr.status === 200) { | |
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getAllResponseHeaders | |
const rawHeaders = xhr.getAllResponseHeaders(); | |
const headerArray = rawHeaders.trim().split(/[\r\n]+/); | |
const headers = headerMap(headerArray); | |
// return a Response to be compatible with `fetch` | |
// https://developer.mozilla.org/en-US/docs/Web/API/Response | |
const response = new Response(xhr.responseText, { | |
status: xhr.status, | |
statusText: xhr.statusText, | |
headers, | |
}); | |
resolve(response); | |
} else { | |
reject({ failed: xhr.statusText }); | |
} | |
}; | |
xhr.onerror = () => reject({ error: xhr.statusText }); | |
xhr.onabort = () => reject({ abort: xhr.statusText }); | |
xhr.ontimeout = () => reject({ timeout: xhr.statusText }); | |
xhr.open("GET", url, true); | |
xhr.send(); | |
}); | |
}; | |
})(); | |
const url = "https://markentier.tech/feed.json"; | |
let res = await xhrFetch(url); | |
let json = await res.json(); | |
let headers = Object.fromEntries(res.headers); | |
let r = {json, headers}; | |
r |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment