I added CORS extension to chrome. When called ajax from localhost I got response in the form of XML. If I disabled CORS extension I got the following error. I referred so many questions in this community. But I cant't resolve my problem. It may duplicate but I'm asking this question for help with hope.
XMLHttpRequest cannot load https://buzz.machaao.com/feed. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401..
And my code is
HTTP.get('https://buzz.machaao.com/feed',{
headers: {
"Access-Control-Allow-Origin" : "*"
}
}, (err, res) => {
if(err) {
console.log(err);
}
else {
console.log(res);
}
});
The https://buzz.machaao.com/feed site doesn’t send the Access-Control-Allow-Origin response header, so you need to make your request through a proxy instead—like this:
var proxyUrl = 'https://cors-anywhere.herokuapp.com/',
targetUrl = 'http://catfacts-api.appspot.com/api/facts?number=99'
HTTP.get(proxyUrl + targetUrl,
(err, res) => {
if(err) {
console.log(err);
}
else {
console.log(res);
}
});
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS explains why 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.
https://buzz.machaao.com/feed 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 even see it in browser devtools—but your browser won’t expose it to your code unless it has a 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.
Related
I have a firebase function that works perfectly well when I'm running it on my local machine. It sends an email. This is the code:
exports.sendEmail = functions.https.onRequest((req, res) => {
const msg = req.query
return sgMail.send(msg)
.then(mailResponse => {
return cors(req, res, () => {
res.status(200).send(mailResponse)
})
})
.catch(err => {
return cors(req, res, () => {
console.log(err)
res.status(200).send(err)
})
})
})
However, when it is deployed, whether I'm requesting it from my local machine or from my hosted deployment with firebase, I encounter this error:
Access to XMLHttpRequest at ... from origin ... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
However, if the request is small enough, then it goes through, fires the function correctly, and produces no error. It's only when I try to push through a relatively large email that has a lot of report data that I encounter this issue.
I tried to switch from a GET to a POST request but this seemed to have no effect.
The firebase functions log says things like Function execution took 696 ms, finished with status: 'connection error' when the error happens.
As per Google documentation for HTTP functions, you may get errors like that if cross-origin resource sharing (CORS) isn't set up properly.
CORS consists of two requests: a preflight OPTIONS request, and a main request that follows the OPTIONS request.
The preflight request contains headers indicating method and additional headers, which will be sent in the main request, as well as the origin of the main request.
To handle a preflight request, you must set the appropriate Access-Control-Allow-* headers to match the requests you want to accept. Please see this link for an example.
Frontend runs at localhost:3000
Server runs at localhost:9000
I am able to make a CORS requests without access to cookies.
Sample Axios Request
axios.post(SERVER+'/createUser', params)
.then( resp=>{
//not important
});
(working: able to access resources from other server)
I was unable to save/send the HttpOnly cookie [session implementation] that the server localhost:9000 sets
Expected Process Flow
Call to localhost:9000/authenticate
localhost:9000/authenticate returns a response with a HttpOnly cookie
subsequent requests to localhost:9000 carry this cookie
To try to access this cookie with axios I added the header withCredentials:true
referenced by the documentation for axios. For clarity:
let headers = {
withCredentials:true
}
export function authenticate(creds){
return dispatch => {
axios.post(SERVER+'/authenticate', creds, headers)
.then( resp => {
//not important
});
};
}
After which I received the following error:
Failed to load http://localhost:9000/authenticate: Response to
preflight request doesn't pass access control check: 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'. Origin
'http://localhost:3000' is therefore not allowed access. The
credentials mode of requests initiated by the XMLHttpRequest is
controlled by the withCredentials attribute.
For clarity, the first (OPTIONS) request is sent and after a 'successful' response, the error is thrown. OPTIONS request:
My server uses Flask-Cors library, after reading the cookie documentation and a few other links, this is how the server is setup for CORS
... normal app init
app = Flask(__name__, static_url_path='/static')
...
cors = CORS(app, origins=["http://localhost:3000"], headers=['Content-Type'], expose_headers=['Access-Control-Allow-Origin'], supports_credentials=True)
...
#app.route('/authenticate', methods=['POST'])
def authenticate():
...
I only set the method as POST because (1) the cookie documentation also restricted it to POST and (2) the OPTIONS request seemingly goes through (as referenced by the image) and (3) when I do include OPTIONS as a possible method for the route, when the first request is sent it goes into the method and I have no idea what to return so if someone knows what is the correct response when the OPTIONS method is included please do post.
Other Links
https://github.com/axios/axios/issues/569
Why does my JavaScript get a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when Postman does not?
CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true
Set-Cookie header has no effect
The code looks like you are defining withCredentials as a HTTP header. But that's not exaclty how it works.
withCredentials is actually an option which will enable a http header, but it's not a http header in itself.
Try creating the promise like this:
const axiosWithCookies = axios.create({
withCredentials: true
});
const promise = axiosWithCookies.get(url);
The resulting http header will actually look as follows.
But you don't have to add this manually. This will be taken care of if you create the axios instance as above.
Cookie: JSESSIONID=...
I'm trying to access web service from my angular service with cross-origin related headers set. But still, I'm not able to access the web service. The browser keeps saying,
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.
I'm able to access the same URL in the browser (chrome) and postman but not in angular application.
private headers = new HttpHeaders()
.set('Access-Control-Allow-Origin', '*')
.set('Content-Type', 'application/json;charset=UTF-8')
.set('Access-Control-Allow-Headers', '*')
.set('Access-Control-Allow-Methods', 'GET, OPTIONS');
public getData(): Promise<Object> {
return this._http.get(this._url, {headers: this.headers})
.toPromise()
.then(response => {
return response;
}
)
.catch(testService.handleError);
}
Is there anything I'm missing here...
There are multiple ways to solve this issue, but first you will need to identify the extra request header parameter that is getting send by the client, if any.
It's earlier to spot this by using any of the broswer's developer console. Another pointer is to check the response/error for options call if any.
Once identified, you will need to enable the appropriate response parameters from the server, in your case it seems the options call is not setting Access-Control-Allow-Origin in the response.
Let me know if this helped you diagnose your issue.
Try JSONP. Basically as per WC3Schools states
JSONP is a method for sending JSON data without worrying about cross-domain issues.
JSONP does not use the XMLHttpRequest object.
Here's an explanation of how JSONP works
So, there is two approaches
If you have an access to edit the web service.
You need to allow Cross Origin Resource sharing.
if u are using Node.js here is an example of code to add
// ~ Cross origin resource sharing ~ //
var cors = require('cors');
// ~ Initialize the app ~ //
var app = express();
// ~ Enbling CORS ~ //
app.use(cors());
You can add a browser extension that enables you fix CORS errors for the angular app while running on browser.
Here is for chrome https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en
Here is for Mozilla https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/
You can read more at https://enable-cors.org/
I hope that helps. If there is any error let me know through comments.
I'm trying to access the Deezer API from localhost, but I'm keep getting the following error:
Fetch API cannot load http://api.deezer.com/search/track/autocomplete?limit=1&q=eminem.
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost' 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.
localhost's response's headers does have Access-Control-Allow-Origin header
(Access-Control-Allow-Origin:*).
I'm using fetch like:
fetch('http://api.deezer.com/search/track/autocomplete?limit=1&q=eminem').
What am I doing wrong?
You can make the request through a public CORS proxy; to do that try changing your code to:
fetch('https://cors-anywhere.herokuapp.com/http://api.deezer.com/search/track/autocomplete?limit=1&q=eminem')
That sends the request through https://cors-anywhere.herokuapp.com, which forwards the request to http://api.deezer.com/search/track/autocomplete?limit=1&q=eminem and then receives the response. The https://cors-anywhere.herokuapp.com backend adds the Access-Control-Allow-Origin header to the response and passes that back to your requesting frontend code.
The browser will then allow your frontend code to access the response, because that response with the Access-Control-Allow-Origin response header is what the browser sees.
You can also set up your own CORS proxy using https://github.com/Rob--W/cors-anywhere/
For details about what browsers do when you send cross-origin requests from frontend JS code using XHR or the Fetch API or AJAX methods from JavaScript libraries—and details about what response headers must be received in order for browsers to allow frontend code to access the responses—see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.
For now, it is impossible to make this request. You can proxy request to API from your own backend or use jsonp. Here is a library with fetch-like syntax https://github.com/camsong/fetch-jsonp. Usage example https://jsfiddle.net/4dmfo0dd/1/
fetchJsonp('https://api.deezer.com/search/track/autocomplete?limit=1&q=eminem&output=jsonp')
.then(function(response) {
return response.json();
})
.then(json => console.log(json))
.catch(function(error) { console.log(error); });
CORS or Cross Origin requests made to servers
http://api.deezer.com/search/track/autocomplete?limit=1&q=eminem
in this case, have a preflight check enabled by all modern browsers.
and usually fail, if the server does not respond with Access-control headers.
In case of a fetch too, since you are basically fiddling with Javascript ,
You Need the Server to respond with Access-control-Allow-Origin Headers, which are flexible.
You Can not do Much about it Unless, the API itself becomes flexible and more open.
You however can Use fetch with mode set to no-cors
IFFF you only wish to cache the result of the request you make, to serve as a response, and not consume it yourself
Read Opaque Responses
No-CORS Definition
no-cors — Prevents the method from being anything other than HEAD, GET or POST. If any ServiceWorkers intercept these requests, they may not add or override any headers except for these. 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
In the browser, I'm doing an HTTP request. The resource at reqUrl doesn't enable CORS, so there's no response body. But how can I get the response header? (I can see it in the DevTools' network tab.)
var p = fetch(reqUrl, {
method: "POST",
headers: reqHeader,
body: reqBody
});
p.then(function () {
})
.catch(function (err) {
// CORS is disabled so I'm arriving here
// "TypeError: NetworkError when attempting to fetch resource."
});
You can't, unless it supports CORS and has the header name white-listed. This is a security matter since getting forbidden header content is as risky as forbidden response content. The dev tools feature is not restricted by the SOP, so it doesn't need such "perms" to show the user debug information. You cannot reach any devtool info by scripts, so it's safe just to show to the user.