Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get "Fetch failed loading" when it actually worked?

I use the following code to POST the users position to my own backend-service via the Fetch API:

window.onload = () => {
    let getPosition = (options) => {
        return new Promise((resolve, reject) => {
            navigator.geolocation.getCurrentPosition(resolve, reject, options);
        });
    };

    getPosition().then(pos => {
        const data = new FormData();
        data.append('latitude', String(pos.coords.latitude));
        data.append('longitude', String(pos.coords.longitude));

        fetch('/', {             // <--- error is thrown in this line
            method: 'POST',
            body: data
        }).then(response => {
            if (!response.ok) {
                throw Error('Data sent - Network response NOT OK');
            } else {
                console.log('Data sent - Network response OK')
            }
        });
    });
};

This works flawlessly and the backend-service sends back a positive empty response. Data sent - Network response OK is logged in the browser's console and everything is fine except that immediately after, this is logged:

enter image description here

How come I get a Fetch failed loading: POST even though the POST succeeded, the response is OK and the status code in the Chrome network tab is 200 OK? Is there something wrong with my code?

like image 245
leonheess Avatar asked Aug 13 '19 12:08

leonheess


People also ask

Why did fetch fail?

The "TypeError: Failed to fetch" occurs for multiple reasons: An incorrect or incomplete URL has been passed to the fetch() method. The server you are making a request to does not send back the correct CORS headers. A wrong protocol is specified in the url.

How do you deal with failure to fetch?

The fetch() function will automatically throw an error for network errors but not for HTTP errors such as 4xx or 5xx responses. For HTTP errors we can check the response. ok property to see if the request failed and reject the promise ourselves by calling return Promise.

What is a failed to fetch error?

When you see an error saying "Failed to fetch" or get an ICE error this means that there is a connectivity issue between you and Lookback. Typically this is related to a firewall blocking your connection in some way.

Does fetch throw error 404?

A fetch() promise only rejects when a network error is encountered (which is usually when there's a permissions issue or similar). A fetch() promise does not reject on HTTP errors ( 404 , etc.). Instead, a then() handler must check the Response.ok and/or Response.status properties.


2 Answers

I had the same behaviour that you were seeing. My server responded to the POST request with a 204 (Empty Response) and an empty (Content-Length=0) response. I tried changing that to just respond with a "ok" message instead (edit: actually just returning the created object now) and the fetch error log disappeared.

It seems to me that fetch (at least in Chrome) erroneously logs "Fetch Failed" when the response body is empty, even if the request was successful.

like image 85
rewolf Avatar answered Sep 19 '22 12:09

rewolf


This happens because you don't read the empty response body. I noticed this, because Django triggers a broken pipe error on the server side. To fix this, just read the empty body out.

async function fetchSomething() {
    const response = await fetch(url, {
        method: 'POST'
    })
    await response.text()
    return response.ok
}
like image 30
TheHippo Avatar answered Sep 18 '22 12:09

TheHippo