Hello folks,
I stumbled upon a really strange bug, that only occurred in WebWorkers when using Safari (Desktop).
At this point https://github.com/sindresorhus/ky/blob/master/index.js#L262 ky accesses the document object. There is a check for it, but in case it is not present, globals.document && globals.document.baseURI returns false. But i think Safari expects a string or undefined, because it throws a Type Error at exactly this position. https://developer.mozilla.org/en-US/docs/Web/API/URL/URL this is the documentation for the URL class.
Am i right with my findings? If so, i'd be willing to submit a PR.
Thanks for the awesome package and for your help in advance!
Edit: I just realized, that globals.document && globals.document.baseURI returns undefined in case of globals.document not being existant. So I really have no idea now why Safari throws a TypeError.
Does it work if input is an absolute URL? The type error may be happening because neither argument to new URL() includes a protocol.
We could work around this by parsing the URL manually, but it's a bit hacky. I desperately want a URL constructor that handles relative URLs. new URL(new Request(myUrl).url) works, but is ugly.
Can you put the error here? It would be very helpful to investigate the issue.
Hey, input already is an absolute URL. To reproduce the problem you can just enter
new URL('http://google.com', undefined);
into the web developer console. You'll get this:

This works perfectly fine in Firefox. So it seems to be Safari-only behavior.
This is from the Safari Developer Tools. At this line the TypeError is thrown.

Confirmed. Thanks for the repro.
Unfortunately, this seems to be a bug in Safari, and I believe it violates the specification.
I did come up with a potential workaround, though...
diff --git a/index.js b/index.js
index badfca6..a5bdae0 100644
--- a/index.js
+++ b/index.js
@@ -259,7 +259,7 @@ class Ky {
this._input = this._options.prefixUrl + this._input;
if (searchParams) {
- const url = new URL(this._input, globals.document && globals.document.baseURI);
+ const url = new URL(new Request(this._input).url);
if (typeof searchParams === 'string' || (URLSearchParams && searchParams instanceof URLSearchParams)) {
url.search = searchParams;
} else if (Object.values(searchParams).every(param => typeof param === 'number' || typeof param === 'string')) {
What's nice about this is that the Request class actually handles the base URL stuff for us automatically.
It would be great if you could tell me what new Request('/foo').url does inside of a Safari WebWorker. Hopefully it just passes the relative URL right through (as Deno does) rather than throwing an error.
Regardless, I will implement this after the request work in PR #180 lands, as it's a nice simplification.
It would be great if you could tell me what
new Request('/foo').urldoes inside of a Safari WebWorker. Hopefully it just passes the relative URL right through (as Deno does) rather than throwing an error.
Does not throw an error.
console.log(new Request('/foo').url); prints https://localhost:8000/foo in usual Safari context, as well as in WebWorker.
Also:
Much thanks for your fast reply and for the fix! 馃憤
Nice. 馃憣
You're welcome! PR coming in the next day or two, which will include fixes for a few issues, including this one.
Most helpful comment
Nice. 馃憣
You're welcome! PR coming in the next day or two, which will include fixes for a few issues, including this one.