Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify whether fetch method and Request accept URL instances #452

Closed
mislav opened this issue Jan 13, 2017 · 3 comments
Closed

Clarify whether fetch method and Request accept URL instances #452

mislav opened this issue Jan 13, 2017 · 3 comments

Comments

@mislav
Copy link

mislav commented Jan 13, 2017

In fetch(url) and new Request(url) invocations, can url be an instance of URL? The spec is not clear.

This example shows that fetch() should likely accept URL:

var url = new URL("https://geo.example.org/api"),
    params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)

However, when I look at the spec itself, the first argument for Request constructor is defined as "RequestInfo", and later on it states:

5. If input is a string, then run these substeps: …
6. Otherwise (input is a Request object), run these substeps: …

This suggests that the argument may only be "USVString" or Request, and that behavior concerning other types is undefined, or—as I interpret it—that any non-string type will be treated as Request and that an exception will be thrown if the type doesn't look like a Request.

The spec also suggests that the behavior of the fetch() method is identical to new Request() because the arguments to fetch() are forwarded to Request constructor. It follows that fetch() too only accepts string or Request as argument.

Google Chrome's implementation, however, seems to treat any non-Request argument as a url by converting it to a string. Example:

new Request({ toString: () => "foo" }).url
// => "https://github.com/whatwg/fetch/issues/foo"
@annevk
Copy link
Member

annevk commented Jan 13, 2017

Welkom!

Part of the behavior of the API is defined through IDL. So https://fetch.spec.whatwg.org/#requestinfo is indeed either a Request or a string. However, what that means is that the binding layer (the bit IDL defines) will first check if the passed argument is a Request object and otherwise invoke ToString() on it (plus a couple of other things). And URL objects in turn, have a toString() defined (basically returning the value that the href getter returns). Combined, that gives the behavior you are observing.

Going to tentatively close this, but I'll happily respond to any further queries.

@annevk annevk closed this as completed Jan 13, 2017
@mislav
Copy link
Author

mislav commented Jan 13, 2017

Thanks for explaining! I guess we will have to tweak our polyfill to match this behavior. I wasn't aware that this conversion happens at the binding layer (I have little familiarity with IDL). But, the end behavior makes sense to me.

@annevk
Copy link
Member

annevk commented Jan 13, 2017

See https://heycam.github.io/webidl/#es-USVString and how https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm handles strings near the end for the full details, but beware, it's rather involved.

mislav added a commit to JakeChampion/fetch that referenced this issue Jan 16, 2017
This aims to match the behavior that the IDL of the spec defines:
whatwg/fetch#452 (comment)
mislav added a commit to JakeChampion/fetch that referenced this issue Jan 16, 2017
This aims to match the behavior that the IDL of the spec defines:
whatwg/fetch#452 (comment)
adambene pushed a commit to benestudio/fetch that referenced this issue Feb 27, 2017
This aims to match the behavior that the IDL of the spec defines:
whatwg/fetch#452 (comment)
mislav added a commit to mislav/flow that referenced this issue May 9, 2017
A URL instance is a valid argument to `fetch(url)` and `new Request(url)`.
It's not mentioned explicitly in the spec:

    typedef (Request or USVString) RequestInfo;

But, technically, any non-Request object that implements `toString()` is
a valid argument, since it will be converted into string:
whatwg/fetch#452 (comment)

However, I didn't want to allow `any` as a type for RequestInfo, since
that basically eliminates the benefit of typechecking the first argument.
I'm not sure what the best approach to this would be, so in the meantime
I have just added "URL" to the RequestInfo union.
cr313 added a commit to cr313/fetch-Js-flow that referenced this issue Apr 19, 2024
This aims to match the behavior that the IDL of the spec defines:
whatwg/fetch#452 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants