Trying to use fetch and pass in mode: no-cors

后端 未结 6 853
悲&欢浪女
悲&欢浪女 2020-11-22 02:33

I can hit this endpoint, http://catfacts-api.appspot.com/api/facts?number=99 via Postman and it returns JSON

Additionally I am using create

6条回答
  •  没有蜡笔的小新
    2020-11-22 03:12

    mode: 'no-cors' won’t magically make things work. In fact it makes things worse, because one effect it has is to tell browsers, “Block my frontend JavaScript code from looking at contents of the response body and headers under all circumstances.” Of course you almost never want that.

    What happens with cross-origin requests from frontend JavaScript is that browsers by default block frontend code from accessing resources cross-origin. If Access-Control-Allow-Origin is in a response, then browsers will relax that blocking and allow your code to access the response.

    But if a site sends no Access-Control-Allow-Origin in its responses, your frontend code can’t directly access responses from that site. In particular, you can’t fix it by specifying mode: 'no-cors' (in fact that’ll ensure your frontend code can’t access the response contents).

    However, one thing that will work: if you send your request through a CORS proxy, like this:

    var proxyUrl = 'https://cors-anywhere.herokuapp.com/',
        targetUrl = 'http://catfacts-api.appspot.com/api/facts?number=99'
    fetch(proxyUrl + targetUrl)
      .then(blob => blob.json())
      .then(data => {
        console.table(data);
        document.querySelector("pre").innerHTML = JSON.stringify(data, null, 2);
        return data;
      })
      .catch(e => {
        console.log(e);
        return e;
      });

    Note: if when you go to try to use https://cors-anywhere.herokuapp.com, you find it’s down, you can also easily deploy your own proxy to Heroku in literally just 2-3 minutes, with 5 commands:

    git clone https://github.com/Rob--W/cors-anywhere.git
    cd cors-anywhere/
    npm install
    heroku create
    git push heroku master
    

    After running those commands, you’ll end up with your own CORS Anywhere server running at, e.g., https://cryptic-headland-94862.herokuapp.com/. So then rather than prefixing your request URL with https://cors-anywhere.herokuapp.com, prefix it instead with the URL for your own instance; e.g., https://cryptic-headland-94862.herokuapp.com/https://example.com.


    I can hit this endpoint, http://catfacts-api.appspot.com/api/facts?number=99 via Postman

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS explains why it is that even though you can access the response with Postman, browsers won’t let you access the response cross-origin from frontend JavaScript code running in a web app unless the response includes an Access-Control-Allow-Origin response header.

    http://catfacts-api.appspot.com/api/facts?number=99 has no Access-Control-Allow-Origin response header, so there’s no way your frontend code can access the response cross-origin.

    Your browser can get the response fine and you can see it in Postman and even in browser devtools—but that doesn’t mean browsers will expose it to your code. They won’t, because it has no Access-Control-Allow-Origin response header. So you must instead use a proxy to get it.

    The proxy makes the request to that site, gets the response, adds the Access-Control-Allow-Origin response header and any other CORS headers needed, then passes that back to your requesting code. And that response with the Access-Control-Allow-Origin header added is what the browser sees, so the browser lets your frontend code actually access the response.


    So I am trying to pass in an object, to my Fetch which will disable CORS

    You don’t want to do that. To be clear, when you say you want to “disable CORS” it seems you actually mean you want to disable the same-origin policy. CORS itself is actually a way to do that — CORS is a way to loosen the same-origin policy, not a way to restrict it.

    But anyway, it’s true you can — in just your local environment — do things like give your browser runtime flags to disable security and run insecurely, or you can install a browser extension locally to get around the same-origin policy, but all that does is change the situation just for you locally.

    No matter what you change locally, anybody else trying to use your app is still going to run into the same-origin policy, and there’s no way you can disable that for other users of your app.

    You most likely never want to use mode: 'no-cors' in practice except in a few limited cases, and even then only if you know exactly what you’re doing and what the effects are. That’s because what setting mode: 'no-cors' actually says to the browser is, “Block my frontend JavaScript code from looking into the contents of the response body and headers under all circumstances.” In most cases that’s obviously really not what you want.


    As far as the cases when you would want to consider using mode: 'no-cors', see the answer at What limitations apply to opaque responses? for the details. The gist of it is that the cases are:

    • In the limited case when you’re using JavaScript to put content from another origin into a

提交回复
热议问题