Xmlhttprequest Cross site domain issue? - javascript

been stuck with an issue for sometime and not getting the best solution for this yet.
I am calling an xmlhttprequest (POST)from a javascript residing at server say 'http://localhost:8080' to another server 'http://localhost:9090'
Getting an browser error As mentioned below:
Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)"  nsresult: "0x80004005 (NS_ERROR_FAILURE)" 
 
The error doesnt point anything specific either. Did test the same by calling from same server and worked fine. But i am looking at two server architecture.
Any resolution/ideas ? Saw few posts on setting response headers with cross domain origin as '*',but not sure exactly how to set response headers for xmlhhtprequest calls?

Since the origins of the entities that are trying to communicate are the same in the host part but different in the port part (localhost:8080 <-> localhost:9090) -- this violates the same origin policy and the browser throws an error. See this for more info: http://en.wikipedia.org/wiki/Same_origin_policy
The way to get around this is to use CORS headers in the HTTP responses returned by the server. The fact that you are using XHR to generate the HTTP requests makes no difference. Basically, what you need to do is add a Access-Control-Allow-Origin: * or Access-Control-Allow-Origin: http://localhost:8080 to your responses for POST requests to http://localhost:9090. This of course assumes that you have control over the server resource you are POSTing to so that you can modify the response headers. See this for more info: http://enable-cors.org/ and http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing

Related

How to force authentication in preflight request?

I'm trying to call Github REST API from client-side javascript (in browser).
My code does the following (I'm trying to get a zip containing the branch mkdocs_page of a private repository) :
const endpoint = 'https://api.github.com';
const resource = '/repos/astariul/private-gh-pages/zipball/mkdocs_page';
const options = {
mode: 'cors',
headers: {
'Authorization': 'Basic ' + btoa(`${pat}`), // pat contains my Personal Access Token
}
}
return fetch(`${endpoint}${resource}`, options);
But it does not work :
The preflight request fails with 404.
The console error message :
Access to fetch at 'https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
In the process of debugging this, I tried to reproduce the problem with curl. And when I specify an authenticated request, it works :
curl --user "<my_PAT_token>" -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 204 No Content
But if the request is not authenticated, it does not work :
curl -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 404 Not Found
Note : it works fine when I'm trying to get the master branch (authenticated or not). However it fails after, when being redirected :
Access to fetch at 'https://codeload.github.com/astariul/private-gh-pages/legacy.zip/refs/heads/main?token=XXX' (redirected from 'https://api.github.com/repos/astariul/private-gh-pages/zipball') from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
Is it a bug in the Github API ? Or I'm doing something wrong ?
There’s no way to force authentication in a preflight request. The preflight is controlled totally by the browser, and nothing about it is exposed in any way that you can manipulate from frontend JavaScript code. And the requirements for the CORS protocol explicitly prohibit browsers from including any credentials in preflight requests.
For a detailed explanation, see the answer at https://stackoverflow.com/a/45406085/.
Since the preflight involves the browser making an OPTIONS request, then in general, if a server requires authentication for OPTIONS request to a particular resource (which seems to be the case for the GitHub URL cited in the question) that’s not at all necessarily an unintended bug.
That’s because the only normal case in which a preflight is performed and an OPTIONS request is sent is for the case of frontend JavaScript code running in a browser. Requests made from server-side code or from code running in shell/command-line environment or from desktop apps or native mobile apps don’t involve sending an OPTIONS request.
So, lack of support for unauthenticated OPTIONS requests to a particular resource would only be a bug if the provider actually intended it to be used from frontend code running in a browser. In other words, it can instead indicate the provider intentionally doesn’t want it to be used from frontend JavaScript code (which seems to be the case for the URL cited in the question).

HTTP Request to external API blocked by CORS policy from every origin except localhost

I'm creating an Angular application with which I want to use the DEGIRO public API. Something is going wrong with cross-origin requests between my application and the external API.
When I run the application on localhost with ng serve my preflight requests pass the access control check perfectly. However, I run into problems when I run the application with any other origin host like [any IPv4-address]:4200 with ng serve --host [any IPv4-address]. The same problem also occurs after deploying to for example Firebase.
To communicate with the API I use the HttpClientModule with Angular as shown in the image below.
Angular HTTP POST API call
The problem I run into is described to me by the error message below.
"Access to XMLHttpRequest at 'https://trader.degiro.nl/login/secure/login' from origin
'http://192.168.178.120:4200' has been blocked by CORS policy: Response to preflight request
doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the
requested resource."
The main reason this error confuses me is because it doesn't happen from localhost. In the two images below the differences between the preflight request headers(localhost:4200 & 192.168.178.52:4200) are shown. Please note how the only differences are the origin and referer headers. The deployed application on Firebase is also similar like this.
Http request header (localhost)
Http request header (IPv4-address)
I've tried skipping the preflight request by adding a 'content-type': 'text/plain' header, but even the now simple request wouldn't be accepted by the CORS policy.
I have also read several somewhat similar issue's, but none of them matched my case perfectly and neither did their solutions. Next to these I have also read up a bit on CORS. I found this article very informative and helpful. https://www.html5rocks.com/en/tutorials/cors/
I can't think of any more context. I hope this post is clear and you're able to help. Thanks in any case!
Did you request a session with VWD service?
As I can see first you need to make POST request to:
https://degiro.quotecast.vwdservices.com/CORS/request_session?version=1.0.20170315&userToken=YOUR_TOKEN
And provide header:Origin: 'https://trader.degiro.nl'
and provide body: JSON.stringify({referrer: 'https://trader.degiro.nl'})
After you get the session you use that to for example: get latest bid/ask prices for a VWD issue ID
Check this package out, take look at how they managed to get it working.
Cheers :)

Fetch throws "TypeError: Failed to fetch" for successful, same-origin request

We have been encountering inconsistent client errors with a single-page JavaScript application making fetch requests. Of note, they are all same-origin requests.
let request = new Request(url, options);
...
window.fetch(request)
.then(response => response.json())
.then(data => ...)
.catch(error => ...)
Around 5% of the promises are rejecting with the following error despite the server and the browser receiving a 200 OK response:
TypeError: Failed to fetch
I'm stumped... All of my searches lead to discussions about CORS errors. That doesn't seem to apply given these are all same-origin requests. What is causing the fetch to throw the TypeError?
I can confirm using the Network tab in Chrome DevTools that the fetch request completes with a 200 OK response and valid JSON. I can also confirm that the URLs are same-origin. I can also confirm that there are no CORS pre-flight requests. I have reproduced this issue on Chrome 66 and Safari 11.1. However, we've received a stream of error reports from a mix of Chrome and Safari versions, both desktop and mobile.
EDIT:
This does not appear to be a duplicate of the linked question as we are not sending CORS requests, not setting mode: "no-cors", and not setting the Access-Control-Allow-Origin header.
Additionally, I re-ran tests with the mode: 'same-origin' option set explicitly. The requests are (still) successful; however, we (still) receive the intermittent TypeError.
I know that this is an old issue, but after searching the entire evening I want to share my findings so you can spend your time better.
My web app also worked well for most users but from time to time visitors received the error mentioned in the question. I'm not using any complicated infrastructure (reverse proxy etc.) setup nor do I communicate with services on a different domain/protocol/port. I'm just sending a POST request to a PHP-File on the same server where the React app is served from.
The short answer: My problem was that I've sent the request to the backend by using an absolute URL, like https://my-fancy-domain.com/funky_service.php. After changing this to a relative path like /funky-service.php the issue was gone.
My explanation: Most users come to the site without www in the URL, but some users actually do type this part in their address bars (www.my-fancy...). It turned out that the www is part of the origin, so when these users submit the form and send post requests to https://my-fancy... it's technically another origin. This is why the browser expects CORS headers and sometimes even sends an OPTIONS preflight request. When you use a relative path in your JavaScript-Code the post request will also include the www-part (uses the origin from the address bar) -> same-origin -> no CORS hassle. As it only affects visitors that come with the www to your site it also explains the fact that it worked for most users even with the absolute URL.
Also important to know: The request fails in the browser/ JavaScript-Code but is actually sent to the backend (very ugly!).
Let me know if you need more information. Actually, it is very simple but hard to explain (and to find)
The issue could be with the response you are receiving from back-end. If it was working fine on the server then the problem could be with the response headers. Check the Access-Control-Allow-Origin (ACAO) in the response headers. Usually react's fetch API will throw fail to fetch even after receiving response when the response headers' ACAO and the origin of request won't match.
Ref: Getting "TypeError: failed to fetch" when the request hasn't actually failed

I'm not using the wildcard in Access-Control-Allow-Origin, but Chrome says that I am

I'm running an ionic application using ionic serve on port 8080. I do understand the preflight process and I believe I'm getting the right response:
Still, I'm getting this error:
Failed to load https://bla.bla: 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:8080' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Then, the real request (GET) is not being sent.
What is even weirder is that just before this one request, I'm able to send a POST to the same server. The response headers are the same. The only difference in the request is that the Access-Control-Request-Headers is content-type instead of authentication
Any ideas?
Finally found the answer and it was my fault, not a chrome bug.
Thing is, some time ago I tried using this extension:
https://chrome.google.com/webstore/detail/cors-toggle/jioikioepegflmdnbocfhgmpmopmjkim?hl=en
And it didn't work for my needs, but I forgot to uinstall it. Turns out it was having some kind of conflict, since it seems to add an "Access-Control-Allow-Origin: *" header for every response. Thus it would conflict in a request with credentials (I'm guessing the Authentication header does that, not sure why tbh).
Anyway, after I uninstalled it, it's now working fine.

How To Call Medium RSS Feed

Medium has an RSS feed available at https://medium.com/feed/[#username]. I'm trying to fetch all my blog posts using an XMLHTTPRequest. When I test on local, I run into CORs errors. When I turn on CORs Chrome extension, I get a 401 error. Any ideas? Has anyone succeeded in calling Medium RSS?
To get https://medium.com/feed/[#username] content using XHR, you can make the XHR request through a proxy of some kind. For example, trying giving your current XHR code this URL:
https://cors-anywhere.herokuapp.com/https://medium.com/feed/#sideshowbarker
That’ll cause the request to go to https://cors-anywhere.herokuapp.com, a open/public CORS proxy which then sends the request on to https://medium.com/feed/#sideshowbarker.
And when that proxy gets the response, it takes it and adds the Access-Control-Allow-Origin response header to it and then passes that back to your requesting frontend code as the response.
That response with the Access-Control-Allow-Origin response header is what the browser sees, so the error message the browser is showing you now goes away, and the browser allows your frontend JavaScript code to access the response.
Or use the code from https://github.com/Rob--W/cors-anywhere/ or such to set up your own proxy.
The reason you need a proxy is, responses from https://medium.com/feed/[#username] don’t include the Access-Control-Allow-Origin response header, so your browser will refuse to let your frontend JavaScript code access those responses cross-origin.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS has more details.
This is a bug.
Bug has opened. (Dan Abramov approved)

Categories