I am trying to use the following api endpoint using fetch:
https://api.guerrillamail.com/ajax.php?f=check_email&ip=${ip}&agent=${agent}
(outdated documentation)
When I set credentials: 'include' I get the following error:
Access to fetch at 'https://api.guerrillamail.com/ajax.php?...' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
I have to set the flag in order to submit a cookie for authentication.
After googling this problem for 1++ hour, my understanding is the following:
CORS has to be server side allowed to be able to make "none simple" request to an other domain e.g. localhost => guerrillamail.com to prevent abuse, a variable Access-Control-Allow-Origin has to be set to the domains that should be allowed to send requests. A valid option is "*", which means that ALL origins are ok.
For some reason it is not ok though in combination with the credentials: 'include flag.
Do you have any ideas why this wouldnt be allowed?
Do you know what I have to do, in order to to do the request?
And is my understanding about this correct?
The documentation you're referencing no longer applies. In that old documentation, the API was made available over HTTP rather than HTTPS. CORS doesn't apply to HTTP and wouldn't have been a problem.
In the latest documention, that API is provided over HTTPS. To deal with the CORS requirement, they also removed the need for cookies, changing it to subscr_token and sid_token parameters sent as part of the request:
version 1.5, 30th May 2011
- Removed the requirement for cookies, added subscr_token and sid_token parameters
Related
So I've been working on an in browser program that uses fetch to get some data from an api, and because the api only returns data in chunks I need to send a total of 70-100 requests, one after another at about 5/second. However about 50% of the time I get a CORS error:
Access to fetch at 'https://api.hypixel.net/skyblock/auctions?page=49&key=7a5825e3-2d47-4ff4-894f-7fd2a6c9ca17' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Strangely enough, when it does happen, the error seems to occur at a random point through the 80 or so requests. I understand the concept of a CORS proxy but I cannot figure out how to use it in practice. Could someone explain how to use any of the CORS proxy websites to avoid this error.
Did you add this to your package.json:
"proxy": {
"*":{ "target" : "http://myurl"}
}
And set headers like:
axios.defaults.headers.post['Content-Type'] ='application/json;charset=utf-8';
axios.defaults.headers.post['Access-Control-Allow-Origin'] = '*';
Here is my setup:
Running a local angular application on port 4200
Running an API using Deno on port 4300.
I have a use case where a client call at some api endpoint http://localhost:4300/foo, needs to redirect the user to another portion of the front end, say http://localhost:4200/bar#baz.
Currently this fails with the following error:
Access to XMLHttpRequest at 'http://localhost:4200/bar#baz' (redirected from 'http://localhost:4300/foo') from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
I have tried disabling/allowing cors on the API:
ctx.response.headers.set('Acces-Control-Allow-Origin','*');
ctx.response.headers.set('Acces-Control-Allow-Headers','*');
ctx.response.headers.set('Acces-Control-Allow-Methods','*');
ctx.response.headers.set('Access-Control-Allow-Credentials','true');
But this does not work.
Any ideas on how to fix this? Without setting up a proxy or installing a browser plugin.
Thanks!
See MDN:
The value "*" only counts as a special wildcard value for requests without credentials (requests without HTTP cookies or HTTP authentication information). In requests with credentials, it is treated as the literal header name "*" without special semantics. Note that the Authorization header can't be wildcarded and always needs to be listed explicitly.
You are making a request with credentials therefore you can't use * as a wildcard and have to be explicit about which headers you are using.
Using dockerized Ory Kratos and Angular (www folder hosted via nginx to be able to modify headers) on localhost and trying to execute
const headers = {
Accept: 'application/json',
};
fetch('http://127.0.0.1:4433/self-service/registration/browser', {
method: 'GET',
headers,
redirect: 'follow',
credentials: 'include',
})
.then((r) => console.log(r))
.catch((f) => console.log(f));
leads to
Access to fetch at 'http://127.0.0.1:8100/auth/register?flow=b35c3f9a-5592-4121-80b9-87503c38e1d3' (redirected from 'http://127.0.0.1:4433/self-service/registration/browser') from origin 'http://127.0.0.1:8100' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:8100' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
http://127.0.0.1:4433/self-service/registration/browser redirects to http://127.0.0.1:8100/custompath/register?flow=[some-flow-id] via a 302 HTTP response. The browser tries to resolve the redirect and throws the error mentioned above.
Origin and allowed origin are the same - so how can that error happen? I already found this answer on stackoverflow: https://stackoverflow.com/a/62320912/14345380 if that's helpful.
Chrome version 87.0.4280.88
Edit #1
Network tab output can be seen
here
Edit #2
To be able to resolve the issue yourself I set up a little repository: Find it here
Edit #3
Thanks for the hint from pandamakes. The test repo is not running on :8100 but on 4200 (Switched from ionic project to angular project).
Edit #4
I started another discussion at the ory/kratos project origin here. The Ory Team implemented a SDK which we can use instead of plain fetch requests.
One thing is simply add no-cors to the request.
mode: 'no-cors'
Also, you say you have Access-Control-Allow-Origin header set did you also set Access-Control-Allow-Credentials: true , since you are fetching with credentials: "include".
Lastly setting credentials: "include" origin can not be a localhost or 127.0.0.1 or it will return false and cause a cors error, so either, set credentials to same-site or omit or get yourself a domain name.
I ... think I got it...
The 302 redirection works, but when the fetch requests follows the redirection, it now attempts at fetching a non-cors resource. In this event, it will not attach an Origin request header (since it is a non CORS request).
When the response arrives, the browser will compare access-control-allow-origin header, if any exist, to the origin of the request. If the response header exists, and is not *, it must match the origin header of the request.
So solve your issue, you will want to remove the access-control-allow-origin in your nginx setup, or set it to *
min repro: https://github.com/xgui3783/cors-min-repro
I have been trying to use a web API in javascript but I repeatedly keep getting this error:
Access to fetch at
'https://eodhistoricaldata.com/api/fundamentals/AAPL.US?api_token={token}'
from origin 'http://127.0.0.1:5500' has been blocked by CORS policy:
The 'Access-Control-Allow-Origin' header has a value
'https://eodhistoricaldata.com/*' that is not equal to the supplied
origin. Have the server send the header with a valid value, or, if an
opaque response serves your needs, set the request's mode to 'no-cors'
to fetch the resource with CORS disabled.
How should I resolve this? I installed a plugin to set the desirable header but others can't install the plugin to view data.
Perhaps this is what you meant, but it's the HTTP response from your API at 'https://eodhistoricaldata.com/' that must include the Access-Control-Allow-Origin header in its HTTP responses.
If the value of that header is 'https://eodhistoricaldata.com/*', your web browser will trigger a CORS error if you call that API from code hosted in any domain other than 'https://eodhistoricaldata.com'. To fix this, you need to change the value your API returns for this header to the domain you want to allow to call your API.
Returning the value * for the Access-Control-Allow-Origin header will allow applications from any domain to call your API without a CORS error.
I am trying to GET information from this site
https://bitcoinindex.es/api/v0.1/coinbase/usd/btc/last
Using the $http service
After looking all over the internet Here is my code in coffeescript
angular.module('blackmoonApp')
.controller 'PricingCtrl', ($scope, $http) ->
$http.defaults.useXDomain = true
$http.get("https://bitcoinindex.es/api/v0.1/coinbase/usd/btc/last",
headers:
"Access-Control-Allow-Origin": "*"
).success (JSON) ->
console.log JSON
The Result is
"XMLHttpRequest cannot load https://www.bitstamp.net/api/ticker/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access."
I am not sure if the website is blocking me (which wouldn't make sense because it is an API) or if AngularJS isn't able to work with CORS.
Access-Control-Allow-Origin is a response header.
This:
headers:
"Access-Control-Allow-Origin": "*"
… sets a request header.
You need to set it on https://www.bitstamp.net/api/ticker/, not in your JavaScript.
It would defeat the object if any JavaScript could grant itself permission to access any server.
I am not sure if the website is blocking me (which wouldn't make sense because it is an API)
Blocking is the default behaviour. Explicit permission must be granted to allow JavaScript from other origins access. Otherwise anyone with a bitstamp account could have their bitcoins stolen by visiting a website that used the API (since it would be their browser, with their cookies, making the request).
From your code:
$http.get("https://www.bitstamp.net/api/ticker/",
headers:
"Access-Control-Allow-Origin": "*"
)
We see that you are attempting to send the Access-Control-Allow-Origin header in the GET request.
CORS doesn't work that way; the Access-Control-Allow-Origin header must be present in the response sent by the server (and, of course, such header must include the exact same domain of the page that sent the request).
From my tests (unlikely, but your results may differ):
https://bitcoinindex.es/api/v0.1/coinbase/usd/btc/last only allows CORS requests from its own domain (the response had Access-Control-Allow-Origin:https://bitcoinindex.es) which is kind of pointless; and
https://www.bitstamp.net/api/ticker/ didn't have the Access-Control-Allow-Origin header at all.