Skip to content

Commit

Permalink
feat(browser): fetch binary outside Worker scopes
Browse files Browse the repository at this point in the history
Use at your own risk.

See #36
  • Loading branch information
larsgw committed Jun 11, 2023
1 parent 076a368 commit 02611fc
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,4 @@ const metadata = fetch('https://doi.org/10.7717/peerj-cs.214', {
- `headers`
- `credentials` (but not `omit`)
- (Non-spec) `timeout`
- Does not support [binary responses in the main thread](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType#Synchronous_XHR_restrictions)
- CORS limitations apply, of course (note they may be stricter for synchronous requests)
20 changes: 17 additions & 3 deletions browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ function syncFetch (...args) {
// Request
xhr.open(request.method, request.url, false)

let useBinaryEncoding = false
try {
// Only allowed in Worker scope, not available in older browsers
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType#Synchronous_XHR_restrictions
xhr.responseType = 'arraybuffer'
} catch (e) {
// not in Worker scope
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType#Synchronous_XHR_restrictions
// Not in Worker scope; instead, attempt this alternative method
// https://web.archive.org/web/20071103070418/http://mgran.blogspot.com/2006/08/downloading-binary-streams-with.html
xhr.overrideMimeType('text/plain; charset=x-binary')
useBinaryEncoding = true
}

for (const header of request.headers) {
Expand All @@ -29,7 +34,16 @@ function syncFetch (...args) {
let headers = xhr.getAllResponseHeaders()
headers = headers && headers.split('\r\n').filter(Boolean).map(header => header.split(': ', 2))

const response = new syncFetch.Response(xhr.response, {
let body = xhr.response
if (useBinaryEncoding) {
const buffer = Buffer.alloc(body.length)
for (let i = 0; i < body.length; i++) {
buffer[i] = body.charCodeAt(i) & 0xff
}
body = buffer
}

const response = new syncFetch.Response(body, {
headers,
status: xhr.status,
statusText: xhr.statusText
Expand Down

0 comments on commit 02611fc

Please sign in to comment.