Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Request header not set as expected when using 'no-cors' mode with fetch API

I have a fetch where the request types seems to be changing which is messing up my post. I submit my basic form (one field only). Here is the fetch.

      handleSubmit(event, data) {
    //alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
    console.log("SUBMIT STATE::", this.state.value);
    return (
        fetch("//localhost:5000/api/values/dui/", {
            method: "post",
            mode: 'no-cors',
            headers: {
                'Access-Control-Allow-Origin': '*',
                'Content-Type': 'application/json',
                'Accept': 'application/json',                  
            },
            body: JSON.stringify({
                name: this.state.value,
            })
        }).then(response => {
            if (response.status >= 400) {
                this.setState({
                    value: 'no greeting - status > 400'
                });
                throw new Error('no greeting - throw');
            }
            return response.text()
        }).then(data => {
            var myData = JSON.parse(data);
            this.setState({
                greeting: myData.name,
                path: myData.link
            });
        }).catch(() => {
            this.setState({
                value: 'no greeting - cb catch'
            })
        })
    );


}

But when I look at this in fiddler content-type is now 'content-type: text/plain;charset=UTF-8'. Here is the raw Fiddler:

POST http://localhost:5000/api/values/dui/ HTTP/1.1
Host: localhost:5000
Connection: keep-alive
Content-Length: 16
accept: application/json
Origin: http://evil.com/
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

content-type: text/plain;charset=UTF-8 Referer: http://localhost:3000/ Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.8

{"name":"molly"}

In DOM Inspector I just see:

POST http://localhost:5000/api/values/dui/ 415 (Unsupported Media Type)

I also find it strange that 'accept' is lower case as well as 'content-type'. Any reason why this is happening. I haven't found anything specific in my searches yet.

like image 414
Puerto Avatar asked Feb 21 '17 16:02

Puerto


People also ask

What is fetch no-CORS mode?

Supplying request options Note that mode: "no-cors" only allows a limited set of headers in the request: Accept. Accept-Language. Content-Language. Content-Type with a value of application/x-www-form-urlencoded , multipart/form-data , or text/plain.

How do I get the response header from Fetch?

We then fetch this request using fetch() , extract a blob from the response using Response. blob , create an object URL out of it using URL. createObjectURL , and display this in an <img> . Note that at the top of the fetch() block, we log the response headers to the console.


2 Answers

When no-cors mode is set for a request, browsers won’t allow you to set any request headers other than CORS-safelisted request-headers. See the spec requirements about adding headers:

To append a name/value (name/value) pair to a Headers object (headers), run these steps:

  1. Otherwise, if guard is "request-no-cors" and name/value is not a CORS-safelisted request-header, return.

In that algorithm, return equates to “return without adding that header to the Headers object”.

And the reason it’s instead getting set to text/plain;charset=UTF-8 is because the algorithm for the request constructor calls into an extract a body algorithm which includes this step:

Switch on object’s type:

USVString

  • Set Content-Type to text/plain;charset=UTF-8.
like image 99
sideshowbarker Avatar answered Oct 02 '22 08:10

sideshowbarker


So this is what resolved this issue, I switched 'no-cors' to 'cors'. Frankly I thought I had flipped flopped these before because of cross origin issues I was having between my local development workstation and the server I was deploying to but needless to say, when I set this back to mode: 'cors', it all worked again. Both local workstation and server. Why that changes the actual request header, Im not sure. If anyone has answers for that I'll gladly upvote.

Thanks.

like image 27
Puerto Avatar answered Oct 02 '22 09:10

Puerto