Set referer for XMLHttpRequest? - javascript

I am successfully sending a XMLHttpRequest by using:
var createCORSRequest = function(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Most browsers.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// IE8 & IE9
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
};
var url = 'http://www.whatismyip.com';
var method = 'GET';
var xhr = createCORSRequest(method, url);
xhr.onload = function() {
// Success code goes here.
};
xhr.onerror = function() {
// Error code goes here.
};
xhr.setRequestHeader('referer', 'http://www.google.com');
xhr.send();
However, I could not able to define my referer. What is the correct way to add the custom referer?

You cannot. The XMLHttpRequest specification forbids the altering of the referer header (this stops sites lying in it to bypass security checks which some sites use the referer for).
Terminate these steps if header is a case-insensitive match for one of the following headers:
…
Referer
…

You can try something like this:
xhr.setRequestHeader('X-Referer', window.location.href);
And then read this custom X-Referer header.

Answer found on https://www.trustedsec.com/blog/setting-the-referer-header-using-javascript/
You can set it using window.history.replaceState(null, '', 'https://yourwebsite.com/forged/referer')
As far as I know it only works with the same domain, but you can forge the path this way.
See https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState

Related

YQL Console: No definition found for Table htmlstring

I don't know if Yahoo changed something during the night, but what worked yesterday doesn't today...
So if you try this, it will work and return the expected HTML from Google homepage.
If you try this, it will also work as expected.
Now if I try to use JavaScript to call the REST queries provided by YQL Console to do my call, I receive the below message:
{"error": {
"description": "No definition found for Table htmlstring",
"diagnostics": {"url": {
"content": "http://www.datatables.org/data/htmlstring.xml",
"execution-stop-time": "1",
"http-status-message": "Bad Request",
"execution-time": "1",
"http-status-code": "400",
"execution-start-time": "0"
}},
"lang": "en-US"
}}
Here is the JavaScript I use:
var createCORSRequest=function(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 an actual CORS request.
var makeCorsRequest=function(url) {
var deferred=jQuery.Deferred();
var xhr = createCORSRequest('GET', url);
if (!xhr) {
deferred.fail('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function() {
deferred.resolve(JSON.parse(xhr.responseText));
};
xhr.onerror = function() {
deferred.fail('Woops, there was an error making the request.');
};
xhr.send();
return deferred;
}
var resturl = "https://query.yahooapis.com/v1/public/yql?q=env%20%22store%3A%2F%2Fdatatables.org%2Falltableswithkeys%22%3B%20select%20*%20from%20htmlstring%20where%20url%3D%22https%3A%2F%2Fwww.google.com%22&format=json&diagnostics=true&callback=";
makeCorsRequest(resturl).then(function(data) {
console.log(data)
})
Side note: on the YQL Console it works almost all the time, but I received some fails. So I'm wondering if there is an outage of YQL ?
I don't know if it's related but i think that they have been hacked, look this, another header in their servers. Weird link: Yahoo
I don't know if it's related, but the YQL console is failing to return results for RSS queries.
For example, this fails:
select * from rss where url="http://razamazazzle.blogspot.com/feeds/posts/default"

Unable to get JSON output from XMLHttpRequest

I've read a few StackOverflow posts, googled it but still can't get what I want.
I simply want to get a JSON from Google's API and import it to a variable so I can filter it the way I want, the following code is what I have so far:
<!DOCTYPE html>
<html>
<body>
Term: <input type="text" id="field1" value="Mc Donalds in New York"><br>
<button onclick="myFunction()">Search</button>
<script>
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
xhr.responseType = 'json';
} else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
xhr.responseType = 'json';
} else {
xhr = null;
}
return xhr;
}
function myFunction() {
var termo = document.getElementById("field1").value;
var URL = "https://maps.googleapis.com/maps/api/place/textsearch/json?query="+termo.replace(" ","+")+"&key=HIDDEN_KEY";
var data = createCORSRequest('GET',URL);
if (!data) {
throw new Error('CORS not supported');
}
}
</script>
</body>
</html>
When I do:
console.log(data);
I get:
When I do:
JSON.parse(data.responseText);
I get:
Uncaught DOMException: Failed to read the 'responseText' property from
'XMLHttpRequest': The value is only accessible if the object's
'responseType' is '' or 'text' (was 'json').
What should I get on console.log:
https://pastebin.com/4H7MAMcM
How can I get the JSON from XMLHttpRequest correctly?
Also worth mentioning, I'm using Cross-Origin Resource Sharing (CORS) because I couldn't access the domain from my local IP.
--Edit--
Phil thought this was a matter of not being able to return response from a asynchronous, but its wrong, I've tried using Ajax, XMLHttpRequest and now using CORS, the duplicate notation was incorrect, please remove it.
This behaviour is documented on MDN;
If responseType is set to anything other than the empty string or "text", accessing responseText will throw InvalidStateError exception.
Instead, you need to use the response property. Since you specified json as the responseType, response will be a JavaScript object (no need to JSON.parse it).
Aside from this, you'll also need to treat the AJAX request as asynchronous, rather than synchronous. For more info on that, see How do I return the response from an asynchronous call?.
Eventually, you should end up with something like;
function createCORSRequest(method, url, cb) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
xhr.responseType = 'json';
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
cb(this.response);
}
}
xhr.send(null);
} else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
xhr.responseType = 'json';
} else {
xhr = null;
}
return xhr;
}
createCORSRequest('POST', '/echo/json/', function (response) {
console.log(response);
});
https://jsfiddle.net/ez3xt6ys/
However, the browser support seems patchy for this at best; https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response. Instead, it is more common to see the responseType being left as text, and for people to JSON.parse() the responseText property.

CORS request firing without sending form data on window.onbeforeunload event in IE9

I've got a pretty simple function which is designed to grab the form data and send it via a CORS request. Basically it looks like this...
window.onbeforeunload = function() {
formData = getFormData();
logAbandonment(formData);
// return formData;
// alert(formData);
}
function logAbandonment(formData)
{
if(!cors_request) {
cors_request = true;
} else {
return;
}
var url = 'http://mydomain.lan/sub/index.php';
var xhr = createCORSRequest('POST', url);
if (!xhr) {
console.log('Error: CORS not supported.');
}
xhr.send(formData);
}
function createCORSRequest(method, url)
{
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
xhr.onprogress = function () { };
xhr.ontimeout = function () { };
xhr.onerror = function () { };
xhr.onload = function() { };
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
}
function getFormData()
{
if(typeof FormData == 'undefined') {
return serialize(document.getElementById('AppForm'));
} else {
return new FormData(document.getElementById('AppForm'));
}
}
Because this is IE9 I am working with, I am using the XDomainRequest javascript object.
It is successfully firing the ajax request, but here is where I am having a problem. It is firing it without sending the formData unless I uncomment either of the return or alert lines, in which case it works perfectly. When I do that, I can see the correct data it is supposed to be saying in the alert.
Another thing I noticed is this only happens when I either close the browser or close the tab. If I refresh the page, it works exactly like I want it to.
I thought maybe IE9 had some weird method of destroying the dom before the request was finished going out, but unfortunately, I can't figure out a way to set this to async false on XDomainRequest.
I've also tried setting a timeout, but that seems to break it completely.
Not an answer as much as a work-around, but I found this works perfectly when appending the query string onto the end of the url when calling xdr's open method.

How can I make this cross-domain ajax call to an API

I have followed a tutorial (and read many others) on making cross-domain requests, but I can't get it to work. I keep getting the same error:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is the code I'm working with. I'm trying to hit the coinbase API.
// 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() { // All HTML5 Rocks properties support CORS.
var url = 'https://www.coinbase.com/api/v1/prices/historical';
var xhr = createCORSRequest('GET', url); if (!xhr) {
alert('CORS not supported'); return;
} // Response handlers.
xhr.onload = function() {
var text = xhr.responseText; var title = getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
makeCorsRequest();
By default, you're not allowed to make cross-domain AJAX calls. If the target defines a CORS policy, then this rule may be relaxed. Details.
If you control the target, you should be able to get this to work by adding a CORS policy.

Accessing pages on Google Sites to load on my site

Via javascript (jQuery) I'm trying to load the contents of some pages from Google Sites onto elements in pages in a different site. Using jQuery's load I get the expectable:
XMLHttpRequest cannot load https://sites.google.com/site/foo/home. No 'Access-Control-
Allow-Origin' header is present on the requested resource. Origin 'http://bar' is
therefore not allowed access.
I tried with CORS, using the code below (which I found at http://www.html5rocks.com/en/tutorials/cors/), but got the same result.
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;
}
function makeCorsRequest() {
var url = 'https://sites.google.com/site/edumonkihelp/test0';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.onload = function() {return xhr.responseText;};
xhr.onerror = function() {alert('Woops, there was an error making the request.');};
xhr.send();
}
So I guess I have two questions:
1. Can you access the contents of pages in Google Sites?
2. Are there any other similar services out there that would allow you to do so?
Thanks!
According to Google Sites Data API you can use the path parameter to fetch that particular page located at http://sites.google.com/site/siteName/path/to/the/page:
GET /feeds/content/domainName/siteName?path=/path/to/the/page
In order to perform Ccoss-domain requests using jQuery.ajax() specify dataType: 'jsonp'
Example
The example demonstrates how to retrieve page located at https://sites.google.com/site/nokiaofficescontacts/hq:
$.ajax({
url: 'https://sites.google.com/feeds/content/site/nokiaofficescontacts?path=/hq&alt=json',
success: function (data) {
console.log('Page was succesfully retrieved');
console.log(data.feed.entry[0].title); //print Page Title
},
error: function (error) {
console.log(JSON.stringify(error));
},
dataType: 'jsonp'
});
Note: alt=json is specified to request a response in JSON format.

Categories