CORS to fetch .js content - Javascript - javascript

I'm trying to get the content of various .js files from a code that runs on the browser (through plugin).
I have no problem getting .js files that reside on the same server, using XMLHttpRequest but when I need to fetch the content of .js files that are on other domains I'm trying to use CORS but I can't seem to get it to work
This is my code
// Create the XHR object.
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
// Make the actual CORS request.
function makeCorsRequest(url) {
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function() {
return xhr.responseText;
};
xhr.onerror = function() {
alert('There was an error making the request.');
};
xhr.send();
}
When I run:
url = `https://......./javascript.js'
res = makeCORSTRequest(url)
I get the 'There was an error making the request.' error alert, and the console logs
XMLHttpRequest cannot load https://......./javascript.js. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://.....com' is therefore not allowed access.

Your browser will only let your frontend JavaScript code access responses from cross-origin requests when the servers you’re making the requests to explicitly indicate they’re opting in to receiving cross-origin requests, which they do by sending the Access-Control-Allow-Origin response header in their responses.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS has more details.
In cases where a site never sends the Access-Control-Allow-Origin response header, the only way you will be able to get content that site cross-origin is by using a CORS proxy. See the answer at "No 'Access-Control-Allow-Origin' header is present on the requested resource" for details.
Browsers are the only clients that enforce restrictions on cross-origin requests, and they only enforce them on web applications.
That’s why even when you see a No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin … is therefore not allowed access message in your devtools console, you’ll still be able to go to the Network tab in devtools and view the response there.
That’s because the server has sent the response and the browser has received it, but the browser is just refusing to allow your frontend JavaScript code to access the response due to the fact the server sending the response hasn‘t opted into to cross-origin requests by sending the Access-Control-Allow-Origin response header.
The reason you can get the response just fine when you make the request from Python, etc., is that no client other than browsers will refuse to allow your code to access the response if it lacks the Access-Control-Allow-Origin response header. But browsers always will.
And note that in none of this is the server doing any blocking or refusing to respond to any requests. The server always continues to just receive requests and send responses. The only difference is in whether the server sends the Access-Control-Allow-Origin header in the response, or not.

Related

Redirect Failing on CORS Request

I'm trying to download a file in client-side Javascript using the Box API, which redirects the request to a temporary download link once the file has been found. The browser is blocking the redirect, though, throwing the following error:
XMLHttpRequest cannot load https://api.box.com/2.0/files/file-id/content. The request was redirected to 'https://dl.boxcloud.com/d/1/some-big-hash/download', which is disallowed for cross-origin requests that require preflight.
In the Network console I see three requests, the first is an OPTIONS (which must be the pre-flight because the actual code sends a GET) with a 200 response, and the second two are identical GET requests which both get 302'd (the expected response for that API call). Here's the code that makes the request:
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('Authorization', 'Bearer '+MyToken);
xhr.onload = function()
{
//some stuff
}
xhr.onerror = function()
{
//some other stuff
}
xhr.send();
My question is (a): Why are two GETs being sent after the preflight comes back?
And (b): Is there any way I can format the request to allow following the redirect? And (c) if not, can I at least retrieve the redirect URL from the response and follow it with another explicit request? Every response in the console has the 'Access-Control-Allow-Origin' header set with the correct origin.
Thanks
I don't understand why you get three rather than two requests, but the way CORS has worked thus far is that a request with a preflight cannot be redirected. This has changed in the Fetch Standard, but user agents have not yet picked up the change.

CORs does not get enabled when using XMLHttpRequest?

I have spent hours trying to access a resource from a different domain.
http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/ which is referenced in other SO posts states that by simply using XMLHttpRequest in a browser that supports CORS, CORS policy should be enabled. However I am still getting
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.nczonline.net/. This can be fixed by moving the resource to the same domain or enabling CORS.
When using it in Firefox 34 which according to http://caniuse.com/#feat=cors should be sufficient.
I am trying a simple example from http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
<script type="text/javascript">
function log(msg){
var output = $('#output');
output.text(output.text() + " | " + msg);
console.log(msg);
}
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
log("'withCredentials' exist in xhr");
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
log("XDomainRequest is being used");
} else {
xhr = null;
log("xhr is null");
}
return xhr;
}
function main(){
log("Attempting to make CORS request");
var request = createCORSRequest("get", "https://www.nczonline.net/");
if (request){
request.onload = function(){
log("LOADED!");
};
request.send();
}
}
$(window).load(function(){
main();
});
</script>
And I am getting the following output:
Attempting to make CORS request
'withCredentials' exist in xhr
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.nczonline.net/. This can be fixed by moving the resource to the same domain or enabling CORS.
Trying it on fiddle https://jsfiddle.net/zf8ydb9v/ gives same results. Is there another lever somewhere that needs to switched on to be able to use CORS bBesides using XMLHttpRequest?
The same origin policy (which prevents making of CORS requests) is there for your security, not the security of the server: it prevents malicious scripts to access your data on other servers using your cookies.
So, if you want you can still disable it at your own risk, on your browser.
In Chrome/Chromium, if you want to disable the same origin policy you can start it with the --disable-web-security option:
chromium-browser --disable-web-security
Anyway, if you want it to work for your users, they will not able to make CORS requests if they have not disabled this security check in their browsers (which is discouraged if not for testing).
As noted in other answers, some servers can purposely allow this kind of requests if they believe this can be useful and not harmful for their users, and they can do this with the Access-control headers.
Moreover, if you still want to find a way to provide this kind of functionality to the users, you might make a Chrome extension, which is not bound to the same origin policy.
A common solution to this is to make the cross origin request server side, returning the result to your application. You should be careful coding this: passing the url to fetch to the server will easily cause security concerns for your server side software. But if you have to fetch the same url every time, you could hard code it server side, in PHP would look like something like this:
<?php
echo file_get_contents("http://your_cross_request/");
?>
then making an ajax request to this page (which will be from the same origin) will return the content of the remote url.
CORS headers are found in the response sent by the server to your request. If the requested page isn't sending the header, it doesn't matter what you did with the request in a stock browser, you'll get a security error
The relevant CORS headers look like this, the last being the most important one
Access-Control-Allow-Credentials: false
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *
I tried opening "nczonline.net" and when I looked at the response headers I did not see any of these, so the server is not configured to permit being loaded in this way
If you are an administrator of that website, you may want to consider adding the required headers to your responses, perhaps being specific about permitted origins rather than using the wildcard
If you're simply trying to demo your code and want to try it with a third party, load a page which does send these headers e.g. developer.mozilla.org

xhr request Control Origin

I am trying to get xhr request. (The script should run in a loop every 2 seconds)
This is my script:
function getJson() {
var xhr = new XMLHttpRequest();
xhr.open("get", "http://www.oref.org.il/WarningMessages/alerts.json", true);
xhr.onload = function(){
var response = JSON.parse(xhr.responseText);
checkJson(response);
}
xhr.send(null);
setTimeout(arguments.callee, 2000);
}
getJson();
I am getting this error: XMLHttpRequest cannot load http://www.oref.org.il/WarningMessages/alerts.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://klh-dev.com' is therefore not allowed access.
So I searched online and I tried to add few lines to my script but it didnt work:
response.addHeader("Access-Control-Allow-Origin", "http://www.oref.org.il/WarningMessages");
response.addHeader("Access-Control-Allow-Origin", "*");
and I tried this one in external html page
header('Access-Control-Allow-Origin: *');
Nothing worked..
You've run into a set of issue collectively known as Cross-Origin Resource Sharing (CORS). Long story short, browsers typically don't allow scripts to access servers that the script didn't originate from, unless the server explicitly allows it. Since your script's origin http://klh-dev.com is not the same as the request target http://www.oref.org.il, the browser is blocking the request.
There are two possible solutions: 1) modify the server to implement CORS headers (probably not possible unless you are in control of the server) or 2) use JSONP to execute the request (does not work in all cases). So, JSONP or CORS?

CORS AJAX Call not Successful

I have an AJAX call trying to execute the following CORS request to a Web Server (I am currently testing using only the latest version of Chrome):
var xhr = new XMLHttpRequest();
xhr.open("get", "http://www.web_server_url.com/query", true);
xhr.onload = function(){
};
xhr.send(null);
Meanwhile, I am still getting the following message:
XMLHttpRequest cannot load http://www.web_server_url.com/query. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
Would someone know what I am missing?
The reason is exactly what it says in the error: The server at www.web_server_url.com is not allowing the localhost origin. It's up to the server to decide whether to allow the origin of the call. In this case, apparently it's not allowing it.
The way CORS works, the server replies to the request (or a "preflight" request) with headers either allowing or disallowing the origin on the basis of the information the browser sends it.

Javascript: XMLHttpRequest problem with Cross-Origin Resource Sharing

I'm making a JSON request to the Google Places API with:
function load(){
var req = new XMLHttpRequest();
req.open('GET', 'https://maps.googleapis.com/maps/api/place/details/json?reference=CnRhAAAARMUGgu2CeASdhvnbS40Y5y5wwMIqXKfL-n90TSsPvtkdYinuMQfA2gZTjFGuQ85AMx8HTV7axABS7XQgFKyzudGd7JgAeY0iFAUsG5Up64R5LviFkKMMAc2yhrZ1lTh9GqcYCOhfk2b7k8RPGAaPxBIQDRhqoKjsWjPJhSb_6u2tIxoUsGJsEjYhdRiKIo6eow2CQFw5W58&sensor=true&key=xxxxxxxxxxxxx', false);
req.send(null);
if(req.status == 200){
dump(req.responseText);
}
}
But Chrome is returning the error:
XMLHttpRequest cannot load https://maps.googleapis.com/maps/api/place/details/json?reference=CnRhAAAARMUGgu2CeASdhvnbS40Y5y5wwMIqXKfL-n90TSsPvtkdYinuMQfA2gZTjFGuQ85AMx8HTV7axABS7XQgFKyzudGd7JgAeY0iFAUsG5Up64R5LviFkKMMAc2yhrZ1lTh9GqcYCOhfk2b7k8RPGAaPxBIQDRhqoKjsWjPJhSb_6u2tIxoUsGJsEjYhdRiKIo6eow2CQFw5W58&sensor=true&key=xxxxxxxxxxxxxx.
Origin http://sandrayoon.com is not allowed by Access-Control-Allow-Origin.
Is there a way to prevent or circumvent cross-origin resource sharing? I am not very familiar with this security issue.
The only way to prevent this is to send proper Access-Control-Allow-Origin header from the server, which isn't under your control. So the basic answer is no. However you can consider using a server proxy, which would grab data from the server and send it to you from the same host as your client script was served.
Server should response with "Access-Control-Allow-Origin" header in order to let the browser to pass this response to javascript. You can also set "*" to allow any cross-domain requests.
Here is a good intro to the subject.

Categories

Resources