Trying to use fetch and pass in mode: no-cors
up vote
42
down vote
favorite
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-react-app and would like to avoid setting up any server config.
In my client code I am trying to use fetch
to do the same thing, but I get the error:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
So I am trying to pass in an object, to my Fetch which will disable CORS, like so:
fetch('http://catfacts-api.appspot.com/api/facts?number=99', mode: 'no-cors')
.then(blob => blob.json())
.then(data =>
console.table(data);
return data;
)
.catch(e =>
console.log(e);
return e;
);
Interestingly enough the error I get is actually a syntax error with this function. I am not sure my actual fetch
is broken, because when I remove the mode: 'no-cors' object, and supply it with a different URL it works just fine.
I have also tried to pass in the object mode: 'opaque'
, but this returns the original error from above.
I belive all I need to do is disable CORS.. What am I missing?
reactjs cors fetch-api create-react-app
add a comment |
up vote
42
down vote
favorite
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-react-app and would like to avoid setting up any server config.
In my client code I am trying to use fetch
to do the same thing, but I get the error:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
So I am trying to pass in an object, to my Fetch which will disable CORS, like so:
fetch('http://catfacts-api.appspot.com/api/facts?number=99', mode: 'no-cors')
.then(blob => blob.json())
.then(data =>
console.table(data);
return data;
)
.catch(e =>
console.log(e);
return e;
);
Interestingly enough the error I get is actually a syntax error with this function. I am not sure my actual fetch
is broken, because when I remove the mode: 'no-cors' object, and supply it with a different URL it works just fine.
I have also tried to pass in the object mode: 'opaque'
, but this returns the original error from above.
I belive all I need to do is disable CORS.. What am I missing?
reactjs cors fetch-api create-react-app
add a comment |
up vote
42
down vote
favorite
up vote
42
down vote
favorite
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-react-app and would like to avoid setting up any server config.
In my client code I am trying to use fetch
to do the same thing, but I get the error:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
So I am trying to pass in an object, to my Fetch which will disable CORS, like so:
fetch('http://catfacts-api.appspot.com/api/facts?number=99', mode: 'no-cors')
.then(blob => blob.json())
.then(data =>
console.table(data);
return data;
)
.catch(e =>
console.log(e);
return e;
);
Interestingly enough the error I get is actually a syntax error with this function. I am not sure my actual fetch
is broken, because when I remove the mode: 'no-cors' object, and supply it with a different URL it works just fine.
I have also tried to pass in the object mode: 'opaque'
, but this returns the original error from above.
I belive all I need to do is disable CORS.. What am I missing?
reactjs cors fetch-api create-react-app
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-react-app and would like to avoid setting up any server config.
In my client code I am trying to use fetch
to do the same thing, but I get the error:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
So I am trying to pass in an object, to my Fetch which will disable CORS, like so:
fetch('http://catfacts-api.appspot.com/api/facts?number=99', mode: 'no-cors')
.then(blob => blob.json())
.then(data =>
console.table(data);
return data;
)
.catch(e =>
console.log(e);
return e;
);
Interestingly enough the error I get is actually a syntax error with this function. I am not sure my actual fetch
is broken, because when I remove the mode: 'no-cors' object, and supply it with a different URL it works just fine.
I have also tried to pass in the object mode: 'opaque'
, but this returns the original error from above.
I belive all I need to do is disable CORS.. What am I missing?
reactjs cors fetch-api create-react-app
reactjs cors fetch-api create-react-app
edited Apr 7 '17 at 1:07
sideshowbarker
30k136988
30k136988
asked Apr 6 '17 at 17:36
dwww
4181511
4181511
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
65
down vote
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).
However, one thing that will work is 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;
);
<pre></pre>
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 and it returnsJSON
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 make a resource from another origin the content of a
<script>
,<link rel=stylesheet>
,<img>
,<video>
,<audio>
,<object>
,<embed>
, or<iframe>
element (which works because embedding of resources cross-origin is allowed for those) — but for some reason you don’t want to or can’t do that just by having the markup of the document use the resource URL as thehref
orsrc
attribute for the element.When the only thing you want to do with a resource is to cache it. As alluded to in the answer at What limitations apply to opaque responses?, in practice the scenario that applies to is when you’re using Service Workers, in which case the API that’s relevant is the Cache Storage API.
But even in those limited cases, there are some important gotchas to be aware of; see the answer at What limitations apply to opaque responses? for the details.
I have also tried to pass in the object
mode: 'opaque'
There is no mode: 'opaque'
request mode—the opaque
condition is instead just a property of the response, and browsers set that opaque condition on responses if they are from requests that are sent with the no-cors
mode.
But incidentally the word opaque is a pretty clear signal about the nature of the response you end up with: “opaque” means you can’t see it.
Love thecors-anywhere
workaround for simple non-prod use-cases (i.e. fetching some publicly available data). This answer confirms my suspicion thatno-cors
is not common because its OpaqueResponse is not very useful; i.e. "very limited cases"; can anyone explain to me examples whereno-cors
is useful?
– The Red Pea
Sep 29 at 15:42
@TheRedPea See the update I made to the answer here (and that I also added as comments for your question at stackoverflow.com/questions/52569895/…)
– sideshowbarker
Sep 29 at 21:51
I needed to configure my Express server with the CORS.js package - github.com/expressjs/cors - and then I needed to removemode: 'no-cors'
from the fetch request (otherwise the response would be empty)
– James L.
Nov 8 at 22:28
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
65
down vote
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).
However, one thing that will work is 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;
);
<pre></pre>
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 and it returnsJSON
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 make a resource from another origin the content of a
<script>
,<link rel=stylesheet>
,<img>
,<video>
,<audio>
,<object>
,<embed>
, or<iframe>
element (which works because embedding of resources cross-origin is allowed for those) — but for some reason you don’t want to or can’t do that just by having the markup of the document use the resource URL as thehref
orsrc
attribute for the element.When the only thing you want to do with a resource is to cache it. As alluded to in the answer at What limitations apply to opaque responses?, in practice the scenario that applies to is when you’re using Service Workers, in which case the API that’s relevant is the Cache Storage API.
But even in those limited cases, there are some important gotchas to be aware of; see the answer at What limitations apply to opaque responses? for the details.
I have also tried to pass in the object
mode: 'opaque'
There is no mode: 'opaque'
request mode—the opaque
condition is instead just a property of the response, and browsers set that opaque condition on responses if they are from requests that are sent with the no-cors
mode.
But incidentally the word opaque is a pretty clear signal about the nature of the response you end up with: “opaque” means you can’t see it.
Love thecors-anywhere
workaround for simple non-prod use-cases (i.e. fetching some publicly available data). This answer confirms my suspicion thatno-cors
is not common because its OpaqueResponse is not very useful; i.e. "very limited cases"; can anyone explain to me examples whereno-cors
is useful?
– The Red Pea
Sep 29 at 15:42
@TheRedPea See the update I made to the answer here (and that I also added as comments for your question at stackoverflow.com/questions/52569895/…)
– sideshowbarker
Sep 29 at 21:51
I needed to configure my Express server with the CORS.js package - github.com/expressjs/cors - and then I needed to removemode: 'no-cors'
from the fetch request (otherwise the response would be empty)
– James L.
Nov 8 at 22:28
add a comment |
up vote
65
down vote
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).
However, one thing that will work is 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;
);
<pre></pre>
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 and it returnsJSON
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 make a resource from another origin the content of a
<script>
,<link rel=stylesheet>
,<img>
,<video>
,<audio>
,<object>
,<embed>
, or<iframe>
element (which works because embedding of resources cross-origin is allowed for those) — but for some reason you don’t want to or can’t do that just by having the markup of the document use the resource URL as thehref
orsrc
attribute for the element.When the only thing you want to do with a resource is to cache it. As alluded to in the answer at What limitations apply to opaque responses?, in practice the scenario that applies to is when you’re using Service Workers, in which case the API that’s relevant is the Cache Storage API.
But even in those limited cases, there are some important gotchas to be aware of; see the answer at What limitations apply to opaque responses? for the details.
I have also tried to pass in the object
mode: 'opaque'
There is no mode: 'opaque'
request mode—the opaque
condition is instead just a property of the response, and browsers set that opaque condition on responses if they are from requests that are sent with the no-cors
mode.
But incidentally the word opaque is a pretty clear signal about the nature of the response you end up with: “opaque” means you can’t see it.
Love thecors-anywhere
workaround for simple non-prod use-cases (i.e. fetching some publicly available data). This answer confirms my suspicion thatno-cors
is not common because its OpaqueResponse is not very useful; i.e. "very limited cases"; can anyone explain to me examples whereno-cors
is useful?
– The Red Pea
Sep 29 at 15:42
@TheRedPea See the update I made to the answer here (and that I also added as comments for your question at stackoverflow.com/questions/52569895/…)
– sideshowbarker
Sep 29 at 21:51
I needed to configure my Express server with the CORS.js package - github.com/expressjs/cors - and then I needed to removemode: 'no-cors'
from the fetch request (otherwise the response would be empty)
– James L.
Nov 8 at 22:28
add a comment |
up vote
65
down vote
up vote
65
down vote
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).
However, one thing that will work is 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;
);
<pre></pre>
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 and it returnsJSON
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 make a resource from another origin the content of a
<script>
,<link rel=stylesheet>
,<img>
,<video>
,<audio>
,<object>
,<embed>
, or<iframe>
element (which works because embedding of resources cross-origin is allowed for those) — but for some reason you don’t want to or can’t do that just by having the markup of the document use the resource URL as thehref
orsrc
attribute for the element.When the only thing you want to do with a resource is to cache it. As alluded to in the answer at What limitations apply to opaque responses?, in practice the scenario that applies to is when you’re using Service Workers, in which case the API that’s relevant is the Cache Storage API.
But even in those limited cases, there are some important gotchas to be aware of; see the answer at What limitations apply to opaque responses? for the details.
I have also tried to pass in the object
mode: 'opaque'
There is no mode: 'opaque'
request mode—the opaque
condition is instead just a property of the response, and browsers set that opaque condition on responses if they are from requests that are sent with the no-cors
mode.
But incidentally the word opaque is a pretty clear signal about the nature of the response you end up with: “opaque” means you can’t see it.
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).
However, one thing that will work is 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;
);
<pre></pre>
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 and it returnsJSON
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 make a resource from another origin the content of a
<script>
,<link rel=stylesheet>
,<img>
,<video>
,<audio>
,<object>
,<embed>
, or<iframe>
element (which works because embedding of resources cross-origin is allowed for those) — but for some reason you don’t want to or can’t do that just by having the markup of the document use the resource URL as thehref
orsrc
attribute for the element.When the only thing you want to do with a resource is to cache it. As alluded to in the answer at What limitations apply to opaque responses?, in practice the scenario that applies to is when you’re using Service Workers, in which case the API that’s relevant is the Cache Storage API.
But even in those limited cases, there are some important gotchas to be aware of; see the answer at What limitations apply to opaque responses? for the details.
I have also tried to pass in the object
mode: 'opaque'
There is no mode: 'opaque'
request mode—the opaque
condition is instead just a property of the response, and browsers set that opaque condition on responses if they are from requests that are sent with the no-cors
mode.
But incidentally the word opaque is a pretty clear signal about the nature of the response you end up with: “opaque” means you can’t see it.
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;
);
<pre></pre>
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;
);
<pre></pre>
edited Oct 4 at 20:42
answered Apr 7 '17 at 1:08
sideshowbarker
30k136988
30k136988
Love thecors-anywhere
workaround for simple non-prod use-cases (i.e. fetching some publicly available data). This answer confirms my suspicion thatno-cors
is not common because its OpaqueResponse is not very useful; i.e. "very limited cases"; can anyone explain to me examples whereno-cors
is useful?
– The Red Pea
Sep 29 at 15:42
@TheRedPea See the update I made to the answer here (and that I also added as comments for your question at stackoverflow.com/questions/52569895/…)
– sideshowbarker
Sep 29 at 21:51
I needed to configure my Express server with the CORS.js package - github.com/expressjs/cors - and then I needed to removemode: 'no-cors'
from the fetch request (otherwise the response would be empty)
– James L.
Nov 8 at 22:28
add a comment |
Love thecors-anywhere
workaround for simple non-prod use-cases (i.e. fetching some publicly available data). This answer confirms my suspicion thatno-cors
is not common because its OpaqueResponse is not very useful; i.e. "very limited cases"; can anyone explain to me examples whereno-cors
is useful?
– The Red Pea
Sep 29 at 15:42
@TheRedPea See the update I made to the answer here (and that I also added as comments for your question at stackoverflow.com/questions/52569895/…)
– sideshowbarker
Sep 29 at 21:51
I needed to configure my Express server with the CORS.js package - github.com/expressjs/cors - and then I needed to removemode: 'no-cors'
from the fetch request (otherwise the response would be empty)
– James L.
Nov 8 at 22:28
Love the
cors-anywhere
workaround for simple non-prod use-cases (i.e. fetching some publicly available data). This answer confirms my suspicion that no-cors
is not common because its OpaqueResponse is not very useful; i.e. "very limited cases"; can anyone explain to me examples where no-cors
is useful?– The Red Pea
Sep 29 at 15:42
Love the
cors-anywhere
workaround for simple non-prod use-cases (i.e. fetching some publicly available data). This answer confirms my suspicion that no-cors
is not common because its OpaqueResponse is not very useful; i.e. "very limited cases"; can anyone explain to me examples where no-cors
is useful?– The Red Pea
Sep 29 at 15:42
@TheRedPea See the update I made to the answer here (and that I also added as comments for your question at stackoverflow.com/questions/52569895/…)
– sideshowbarker
Sep 29 at 21:51
@TheRedPea See the update I made to the answer here (and that I also added as comments for your question at stackoverflow.com/questions/52569895/…)
– sideshowbarker
Sep 29 at 21:51
I needed to configure my Express server with the CORS.js package - github.com/expressjs/cors - and then I needed to remove
mode: 'no-cors'
from the fetch request (otherwise the response would be empty)– James L.
Nov 8 at 22:28
I needed to configure my Express server with the CORS.js package - github.com/expressjs/cors - and then I needed to remove
mode: 'no-cors'
from the fetch request (otherwise the response would be empty)– James L.
Nov 8 at 22:28
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f43262121%2ftrying-to-use-fetch-and-pass-in-mode-no-cors%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown