How to make CORS request using XMLHttpRequest - javascript

$scope.readFile = function(url){
var doc = new XMLHttpRequest();
doc.onreadystatechange = function() {
if (doc.readyState == XMLHttpRequest.DONE) {
if (doc.responseText == undefined)
return;
$scope.loglines += doc.responseText;
}
}
doc.open("GET", url, true);
doc.send();
}
this is the code i used to get data from same origin using angularJS. how could i impore this to get data fron cross domain

To get data from cross domain, you can't do anything on client side, however you can set CORS on server side so that server allows you to send a cross origin request.
One other bad solution is to disable chrome same origin policy.
Disable same origin policy in Chrome

Related

Userscript cross-origin request failing

My AJAX function:
function ajaxQuery(url, method, param, async, onsuccess, onfailure) {
var xmlHttpRequest = new XMLHttpRequest();
var callback = function(r) { r.status==200 ? (typeof(onsuccess)=='function' && onsuccess(r)) : (typeof(onfailure)=='function' && onfailure(r)); };
if(async) { xmlHttpRequest.onreadystatechange = function() { if(xmlHttpRequest.readyState==4) { callback(xmlHttpRequest); } } }
xmlHttpRequest.open(method, url, async);
xmlHttpRequest.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest');
xmlHttpRequest.withCredentials = true;
if(method == 'POST') { xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); }
xmlHttpRequest.send(param);
if(!async) { callback(xmlHttpRequest); }
}
Function call:
ajaxQuery('http://example.net/index.php', 'GET', null, true, function(r) {
tmp.innerHTML = r.responseText;
nlt = [].map.call(tmp.querySelectorAll('.nlt'), function(x) { return x.textContent; });
});
Headers set in PHP:
header('Access-Control-Allow-Origin: https://example.com');
header('Access-Control-Allow-Origin: https://www.example.com');
header('Access-Control-Allow-Origin: http://example.net');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Credentials: true');
if(!preg_match('%https?:\/\/(www\.)?example\.com%', $_SERVER['HTTP_REFERER']) && !preg_match('%https?:\/\/example\.net%', $_SERVER['HTTP_REFERER'])) { die('No way!'); }
I am calling the userscript from a page that uses https, and my domain uses http. When I try AJAX through http, I get (Firefox) Blocked loading mixed active content. If I switch the query URL to https, the error changes to Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource, even though my PHP script clearly allows for requests from the external site. What am I missing?
In this particular example, my site is "http://example.net" and the external site is "https://www.example.com"
It is impossible to get an external resource through AJAX, JSONP or iFrames if the protocols don't match, at least in Firefox and Chromium, due to stupid "mixed content" restrictions. My website is running over http, and the website for which the userscript has been written has enforced https (meaning trying to request its pages through http automatically redirects to https, so I can't even work around the restriction by opting in for http).
The Access-Control-Allow-Origin header should be the same value as the Origin header as long as you want to allow it.
So. you want to multiple domains. I'm recommend you using 'regex'

Access-Control-Allow-Origin' header contains multiple values 'http://xx.xx.xx.xx:3002, http://xx.xx.xx.xx:3002', but only one is allowed

I have downloaded a windows executable file and I installed it. The service will be listening on localhost:11100 port.
I have a written a javascript code to connect to the port and running this javascript code on any webserver is failing, because server sending multiple Access-Control-Allow-Origin headers in the response.
But if I write my JavaScript code in plain html page locally and open it in browser then it is sending one 'Access-Control-Allow-Origin' in the response.
Below is the Javascript code:
function RDService(){
var url = "http://127.0.0.1:11100";
var xhr;
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer, return version number{
//IE browser
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} else {
//other browser
xhr = new XMLHttpRequest();
}
xhr.open('RDSERVICE', url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4){
var status = xhr.status;
if (status == 200) {
alert(xhr.responseText);
//Capture(); //Call Capture() here if FingerPrint Capture is required inside RDService() call
console.log(xhr.response);
} else {
console.log(xhr.response);
}
}
};
xhr.send();
}
after calling the RDService function below error is throwing by the service:
Failed to load http://127.0.0.1:11100/: Response to preflight request
doesn't pass access control check: The 'Access-Control-Allow-Origin'
header contains multiple values 'http://xx.xx.xx.xx:3002,
http://xx.xx.xx.xx:3002', but only one is allowed. Origin
'http://xx.xx.xx.xx:3002' is therefore not allowed access.
The windows executable should only be returning one domain or * in the Access-Control-Allow-Origin header. This is not an issue with the client side JavaScript.
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: <origin>
*
For requests without credentials, the server may specify "*" as a wildcard, thereby allowing any origin to access the resource.
<origin>
Specifies a URI that may access the resource.
reference:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

MailChimp API 3.0 xhr subscribe 501 error

I am trying to subscribe users to my mailchimp list using this snippet:
function subscribeUser(name, email) {
var xhr = new XMLHttpRequest();
var endpoint = 'https://<dc>.api.mailchimp.com/3.0/lists/<list>/members/';
var data = {};
data.email_address = email;
data.status = "subscribed";
data.merge_fields = {};
data.merge_fields.NAME = name;
xhr.open("POST", endpoint, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Authorization", "apikey <key>");
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
xhr.send(data);
}
It generates this error in chrome:
I am unable to write ajax based services to update lists. Because you guys did not add the Access Control header. I cannot send a simple xhr to your endpoint using a modern browser.
XMLHttpRequest cannot load https://<dc>.api.mailchimp.com/3.0/lists/<list>/members/. 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:8000' is therefore not allowed access. The response had HTTP status code 501.
Mine is a static website and I would like to keep it that way. No backend is needed, hosted on github. So I need a JS solution to this.
They currently do not allow client-side access to their API. Their response to a similar question in comments:
We do not support accessing the API via client-side Javascript to
avoid the security issue of passing your API Key along to your users.

Chrome Extension blocked from a rails API

I am just trying to talk with a REST api on a Rails site.
I am using a Chrome extension and javascript to make a CORSRequest.
I get this error whenever I try to make a request:
XMLHttpRequest cannot load https://MYWEBSITE.com/api/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'chrome-extension://mychomreextensioncode' is therefore not allowed access. The response had HTTP status code 404.
Here is my current code:
function makeCorsRequestLogin() {
var url = "https://MYWEBSITE.com/api/login";
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.onload = function() {
var text = xhr.responseText;
var title = text; //getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.onerror = function() {
alert('Woops, there\'s an error making the request.');
};
var password = document.getElementById("password").value;
var user_name = document.getElementById("username").value;
xhr.send(JSON.stringify({"user_name":user_name, "password":password}));
}
Elsewhere, in the past, people have said that this code solves it. But, I have no idea where this could would go.
# This is used to allow the cross origin POST requests made by confroom kiosk app.
def set_access_control_headers
headers['Access-Control-Allow-Origin'] = "*"
headers['Access-Control-Request-Method'] = %w{GET POST OPTIONS}.join(",")
end
I am only working in JS and HTML on a chrome extension. I do not have access to the ruby site. Can I solve this problem from only my end?
You should define permission for your server domain in the manifest.json.
"permissions": ["https://MYWEBSITE.com/*"]
Also make sure you set the right protocol whether it's http or https.

Ajax request: Refused to set unsafe header

I am trying to play an audio using Google Text-To-Speech. Therefore I need to post a request to their endpoint with the Referer and the User-Agent properly set. This call should return an MP3 that I can play.
However, I get Refused to set unsafe header errors. This is my code. How can I do this?
$.ajax({
url: 'http://translate.google.com/translate_tts?ie=UTF-8&q=Hello&tl=en&client=t',
beforeSend: function(xhr) {
xhr.setRequestHeader("Referer", "http://translate.google.com/");
xhr.setRequestHeader("User-Agent", "stagefright/1.2 (Linux;Android 5.0)");
}, success: function(data){
el.mp3 = new Audio(data);
el.mp3.play();
}
});
You can't. It is impossible.
The specification requires that the browser abort the setRequestHeader method if you try to set the Referer header (it used to be that User-Agent was also forbidden but that has changed)..
If you need to set Referer manually then you'll need to make the request from your server and not your visitor's browser.
(That said, if you need to be deceptive about the user agent or referer then you are probably trying to use the service in a fashion that the owner of it does not want, so you should respect that and stop trying).
Note that while jQuery wraps XHR, the same rules apply to fetch.
Empty Origin and Referer headers with GET XMLHttpRequest from <iframe>
Well actually, it is possible; at least for ordinary web pages.
The trick consists in injecting an XMLHttpRequest
function into an empty <iframe>.
The origin of an empty <iframe> happens to be about://blank, which results in empty Origin and Referer HTTP headers.
HTML:
<iframe id="iframe"></iframe>
JavaScript:
const iframe = document.getElementById('iframe');
const iframeWin = iframe.contentWindow || iframe;
const iframeDoc = iframe.contentDocument || iframeWin.document;
let script = iframeDoc.createElement('SCRIPT');
script.append(`function sendWithoutOrigin(url) {
var request = new XMLHttpRequest();
request.open('GET', url);
request.onreadystatechange = function() {
if(request.readyState === XMLHttpRequest.DONE) {
if(request.status === 200) {
console.log('GET succeeded.');
}
else {
console.warn('GET failed.');
}
}
}
request.send();
}`);
iframeDoc.documentElement.appendChild(script);
JavaScript evocation:
var url = 'https://api.serivce.net/';
url += '?api_key=' + api_write_key;
url += '&field1=' + value;
iframeWin.sendWithoutOrigin(url);
Having the possibility of sending empty Origin and Referer HTTP headers is important to safeguard privacy when using third-party API services. There are instances where the originating domain name may reveal sensitive personal information; like being suggestive of a certain medical condition for example. Think in terms of https://hypochondriasis-support.org :-D
The code was tested by inspecting the requests in a .har file, saved from the Network tab in the F12 Developer View in Vivaldi.
No attempt in setting the User-Agent header was made. Please, comment if this also works.
There are some header, which browser doesn't allow programmer to set its value in any of the javascript framework (like jQuery, Angular, etc.) or XMLHttpRequest ; while making AJAX request. These are called the forbidden headers: Forbidden Header

Categories

Resources