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

Fetch API fails to set Content-Type automatically #18

Open
thw0rted opened this issue Jan 8, 2018 · 10 comments
Open

Fetch API fails to set Content-Type automatically #18

thw0rted opened this issue Jan 8, 2018 · 10 comments

Comments

@thw0rted
Copy link

thw0rted commented Jan 8, 2018

I have some code along the lines of

let params = new URLSearchParams(...);
let opts = {
  method: "post",
  body: params,
  credential: "same-origin",
};
fetch(url, opts).then(...);

I used this polyfill to get the URLSearchParams constructor working in Edge. This is fine, but in Chrome and Firefox, setting the POST body to a URLSearchParams instance also sets the Content-Type header to application/x-www-form-urlencoded, per the Fetch spec. When using the polyfill, I have to manually set this header value in each Fetch call, using headers in the options object.

It would be great if the polyfill could hook/patch the fetch method to set this value automatically, but I suspect this won't be feasible. In that case, the documentation should be updated to note this additional usage requirement. Ideally, the library could expose a feature test function or a global variable that we could test against before manually setting headers:

if (__URLSEARCHPARAMS_USE_POLYFILL){
  opts.headers = {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"}
}

rather than always overriding the automatically-determined (in fully compliant browsers) content type.

@jerrybendy
Copy link
Owner

Do you use the latest version of this library? The latest version now is 2.0.1.

In fact, I have added this feature on 20 Jul, 2017. Refer to commit 2374527

    /*
     * Apply polifill to global object and append other prototype into it
     */
    self.URLSearchParams = (nativeURLSearchParams && !isSupportObjectConstructor) ?
        new Proxy(nativeURLSearchParams, {
            construct: function(target, args) {
                return new target((new URLSearchParamsPolyfill(args[0]).toString()));
            }
        }) :
        URLSearchParamsPolyfill;

As the code above, I added a Proxy to extend the native URLSearchParams if it has no full feature support.

You can try to update your library to the latest version and try again. If your problem not fixed, please add a comment to this issue and detail which browser and which version you tested.

@thw0rted
Copy link
Author

thw0rted commented Jan 8, 2018

I just added the polyfill from NPM a few hours ago, double checked and it is definitely v2.0.1. The problem I described above is in the current version of Edge, so, 16 I think? I don't have the test system in front of me, I can double check Edge version if important.

I'm not clear on how the commit you've linked to is supposed to address the problem I ran into with fetch.

@jerrybendy
Copy link
Owner

I checked on caniuse, and Edge 16 supports fetch natively, but it doesn't support URLSearchParams. Browsers which both support fetch and URLSearchParams will add a Content-Type: application/x-www-form-urlencoded; charset=utf-8 header to the request. Because of not support URLSearchParams, Edge 16 will not add this header to the request. So it causes your issue.

@thw0rted
Copy link
Author

thw0rted commented Jan 8, 2018

Yes, right, that's what I meant -- this shortcoming should be in the polyfill's documentation, and the workaround/fix would be cleaner if the polyfill exposed nativeURLSearchParams globally (which, again, would need to be documented).

@jerrybendy
Copy link
Owner

As what you said, it won't be feasible to patch the fetch function. I will update the document to explain about this.

And I think... maybe it should expose a property (or anything else) to help checking whether the bowser supports URLSearchParams natively or not, if I can't come up with a better idea to solve this issue...

@jerrybendy
Copy link
Owner

I've added known issues to the documentation to explain this issue and release a new version.

I discovered that there are so many browsers don't both support fetch and URLSearchParams, and they don't support Proxy, too. So it's difficult to extend the native fetch method.

@iaincollins
Copy link

Thanks for the library! This comment should possibly be a separate ticket, but just to say in the README it says this in relation to this issue:

Use with fetch (#18)
Via fetch spec, when passing an URLSearchParams object as a request body, the request should add a header with Content-Type: application/x-www-form-urlencoded; charset=UTF-8. But, browsers which have fetch support but no URLSearchParams have no this behavior.

Via the data of caniuse, there are many browsers support fetch but URLSearchParams. They are:

I think there is a typo in the first sentence and it's not clear exactly what it's trying to explain.

Would be great if someone could clarify. Thanks!

@jerrybendy
Copy link
Owner

@iaincollins You can read the latest version of document here

My English is not so good, and the document has corrected by @ryuhhnn in #23

@rahul-rautwar
Copy link

rahul-rautwar commented Mar 6, 2019

I am using this polyfill, its working fine for Edge v40 but not on IE 11,
I am getting this error msg in console: "Error: unsupported BodyInit type"
Can someone suggest me how can I made it to work on IE11

@thw0rted
Copy link
Author

thw0rted commented Mar 6, 2019

Rahul, does that have anything to do with the Content-Type problem described in this issue? You might need to create a new issue to track your problem. (I noticed that the README does not list what versions of browsers are supported by the polyfill, or at least what versions have been tested -- might be nice to have!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants