how to process fetch response from an 'opaque' type?

35,072

Essentially, you cannot access response body from an opaque request.

Adding mode: 'no-cors' won’t magically make things work. Browsers by default block frontend code from accessing resources cross-origin. If a site sends Access-Control-Allow-Origin in its responses, then browsers will relax that blocking and allow your code to access the response.

But if a site doesn’t send the Access-Control-Allow-Origin header in its responses, then there’s no way your frontend JavaScript code can directly access responses from that site. In particular, specifying mode: 'no-cors' won’t fix that (in fact it’ll just make things worse).

From https://stackoverflow.com/a/43268098/1666071

And also from fetch documentation:

no-cors — Prevents the method from being anything other than HEAD, GET or POST, and the headers from being anything other than simple headers. If any ServiceWorkers intercept these requests, they may not add or override any headers except for those that are simple headers. In addition, JavaScript may not access any properties of the resulting Response. This ensures that ServiceWorkers do not affect the semantics of the Web and prevents security and privacy issues arising from leaking data across domains.

https://developer.mozilla.org/en-US/docs/Web/API/Request/mode

Share:
35,072

Related videos on Youtube

trid3
Author by

trid3

Updated on July 09, 2022

Comments

  • trid3
    trid3 almost 2 years

    I'm trying to correctly interpret the response from a fetch call to an URL, that I think is a json string. I've tried a many variations based on similar posts here, but nothing is getting me useful data to work with. Here is one attempt:

    fetch('http://serverURL/api/ready/', {method: "POST", mode: "no-cors"})
        .then(function(response) { 
            response.json().then(function(data) {
                console.log('data:' + data);
            });
        })
        .catch(function(err) {
            console.log('Fetch Error :-S', err);
        });
    

    This returns a syntax error in the console:

    SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data

    So maybe its not JSON...if I put in a breakpoint on the console.log line, and hover over response (line above), I see the response object (?) with various fields:

    Response object from debugger hover

    Not sure how to interpret that...status:0 suggests it did not get a valid response. However, if I check the Network tab in the developer tools, and click on the fetch line, status there is 200, and the Response window/JSON section shows the message info that you also see if you just put the URL into the browser URL bar directly. As does the "Response payload" section, which shows the JSON string:

    {"msg": "API is ready.", "success": true}

    So...it looks like json, no? But fetch is unable to ingest this as json?

    Here's another variation, but using response.text() instead of response.json()

    fetch('http://serverURL/api/ready/', {method: "POST", mode: "no-cors"})
        .then((response) => {
            console.log(response);
            response.text().then((data) => {
                console.log("data:" + data);
        });
    });
    

    This prints the response object in the console (same as above: ok: false, status:0, type:opaque etc). The second console.log file prints nothing after data:. If I use response.json, again I get the syntax error about end of data as above.

    Any ideas? I realize the server may not be providing what fetch needs or wants, but, it does provide some info (at least when using the URL directly in the browser), which is what I need to then deal with, as json or text or whatever.

    • zerkms
      zerkms about 5 years
      ok: false, status:0, type:opaque <- this is not json
    • Ouroborus
      Ouroborus about 5 years
      Take a look at Using Fetch. They use a slightly different arrangement for handling JSON than what you are using.
    • zerkms
      zerkms about 5 years
      @Ouroborus how is it different there?
    • trid3
      trid3 about 5 years
      @Ouroborus I tried that exact code snipped on the Fetch page, same problem - it returns the JSON.parse syntax error on the return response.json() line.
    • Cees Timmerman
      Cees Timmerman over 3 years
  • trid3
    trid3 about 5 years
    Thanks - I had thought at one point maybe it was the CORS issue, but when I could see the correct response in the Developer tools / network tab, I decided that wasnt the problem. But sounds like it actually is (yes simply adding "no-cors" did seem rather too easy). So...if I understand this, the response is coming back and dev tools/network/response tab can report on it, but other than that, the browser is blocking access to it from the frontend code.
  • Nätu
    Nätu about 4 years
    Thanks a lot! Those who deal the same issue in python flask check this out: flask-cors.readthedocs.io/en/latest
  • djack109
    djack109 over 3 years
    So is there a way around this ? As it would seem it then impossible to test local applications
  • legel
    legel about 3 years
    I was using Quart so I needed to install Quart-CORS
  • Youth overturn
    Youth overturn almost 2 years
    Finally I solved this by requesting from server side. fetch method is restricted by browser because of security. So I request my local server like the url http://localhost:8010/get_file?address=https://www.nato.int/‌​nato-on-the-map/Cont‌​ent/en/main.json On my local server side I use request module of python and it requests successfully.