Userscript cross-origin request failing - javascript

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'

Related

How to POST json data to the server? (CORS error)

My goal
I am doing .aspx file on Microsoft Visual Studio. What I expect is that the system will scan the QR code and then send the JSON data to the server side.
PS. I am using XMLHttpRequest to send the data.
What I Get
First I tried to pass it directly, it does not work so I check its status and readyStats, what it shows is 1(open) and 0(not initialized) (I am expecting 4(done) and 200(ok)) the responseText is null. I then inspected my browser (Google Chrome), the console shows an error "Access to XMLHttpRequest at 'https://website-A.aspx' from origin 'https://localhost:44371' 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."
What I tried
So I searched for solution on stack overflow, most of them says that I need to put in the header Access-Control-Allow-Origin:* to the server, but the problem is I do not have the control of the server but I do contacted them to change the code to try it out, end up Access-Control-Allow-Origin:* doesn't work so I looked for alternative. I tried to use plugin such as Moesif Origin & CORS Changer but it shows "Access to XMLHttpRequest at 'https://website-A.aspx' from origin 'https://localhost:44371' has been blocked by CORS policy: 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'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.".
Below is my code:
function onScanSuccess(qrCodeMessage) {
...
var url = "https://Website-A.aspx";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open("POST", url);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log(xhr.status);
console.log(xhr.responseText);
}
};
//I hardcoded the data for testing
var data = {
"SOME_ID": "Value",
"SOME_TYPE": "Value",
"SOME_ID": "Value",
"SOME_AMT": "Value",
"SOME_AMT_CURRENCY": "Value",
"SOME_DESC": "Value",
...
};
xhr.send(data);
}
Is there anyway to solve this without changing the server side's code or bypassing the CORS?
I wish to solve this by modify the code in the same .aspx only, is it possible?
If my code ain't going to work, is there any other way to do it?
Any helps will be appreciated.
cors must be allowed on server side. your code looks ok.
sorry, i can't use the comment function yet

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

Get JSON API form docker host

I build qBittorrent from Dockertools box. And qBittorrent have a API get torrentlist . It's like that :
GET /query/torrents HTTP/1.1
User-Agent: Fiddler
Host: 127.0.0.1
Cookie: SID=your_sid
But i run it in this host : http://192.168.99.100:8080/ so i use loadJSON() of javascript to catch what i want . But it's always fail .
This in console :
XMLHttpRequest cannot load http://192.168.99.100:8080/query/torrents?filter=uploading&appid=f782f1c06749ea791dcb5d22219adf068a0d16a5a2c7b6686b17459562eb6b4f. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
my code here :
var torrent_peer;
function loadJSON(url, callback) {
var xobj = new XMLHttpRequest();
if (xobj) {
xobj.overrideMimeType("application/json");
xobj.open('GET', url, true); // Replace 'my_data' with the path to your file
xobj.withCredentials = true;
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
};
xobj.send();
}
}
function load() {
loadJSON("http://192.168.99.100:8080/query/torrents?filter=uploading&appid=f782f1c06749ea791dcb5d22219adf068a0d16a5a2c7b6686b17459562eb6b4f", function(response) {
var actual_JSON = JSON.parse(response);
console.log(actual_JSON);
}, 'jsonp');
}
i read some question but it doesn't work. So any one can help me . Thank a lot !
That is because the API does not specify the header that allows you to access it outside the allowed origin. This is probably a security protection of Chrome. Try running
chrome --disable-web-security.
But be careful, by enabling this, you are vulnerable to websites.
Another way to fix this is to add the header into the application's API. I am not sure that your application will allow to add it.
Access-Control-Allow-Origin: *

How to make CORS request using XMLHttpRequest

$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

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