XDomainRequest in IE is giving Access is Denied error - xdomainrequest

This is the code I am using is as follows down below:
I am using IE9 and am unable to see the request being sent in the Network tab. I do have Access-Control headers set in the JSP as:
<% response.setHeader("Access-Control-Allow-Origin", "*");%>
Code to get the AJAX HTML Content from the JSP:
if ($.browser.msie && window.XDomainRequest) {
var xdr = new window.XDomainRequest();
xdr.open("GET", "http://dev01.org:11110/crs/qw/qw.jsp?&_=" + Math.random());
xdr.contentType = "text/plain";
xdr.timeout = 5000;
xdr.onerror = function () {
console.log('we have an error!');
}
xdr.onprogress = function () {
console.log('this sucks!');
};
xdr.ontimeout = function () {
console.log('it timed out!');
};
xdr.onopen = function () {
console.log('we open the xdomainrequest');
};
xdr.onload = function() {
alert(xdr.responseText);
};
xdr.send(null);
} else { ...... }
I am getting a Access is Denied Error. Any help would be much appreciated!

Requests must be targeted to the same scheme as the hosting page
In your example you are doing request to:
http://dev01 ...
And you should do this from HTTP protocol.
For example:
If your site, where js script is located: http://dev.org
You can do this:
xhr = new XDomainRequest();
xhr.open("GET", "http://dev01.org?p=1");
but this throws "Access denied":
xhr = new XDomainRequest();
xhr.open("GET", "https://dev01.org?p=1");

My experience with XDomainRequest is that it doesn't respect Access-Control-Allow-Origin: *. Instead, you must specify the domain. This can be obtained from the HTTP_REFERER header if you need to dynamically generate it, or if you are only expecting requests from one domain you can set it manually. This article might help.
<% response.setHeader("Access-Control-Allow-Origin", "http://dev01.org");%>

Related

BreezeJS intercept server response

Due to an issue with ASP.NET Identity 2.0, the server returns HTTP 200 with a message saying HTTP 400 and I am trying to intercept it in order to redirect the user to the login page. This is the code I have but it seems that the site does not progress any longer. I understand that the issue is resolved in ASP.NET Identity 3.0 but it is not an option right now. Any ideas on the code below?
var ajaxAdapter = breeze.config.getAdapterInstance('ajax');
ajaxAdapter.requestInterceptor = function (requestInfo) {
requestInfo.success = function (response) {
// process response message here.
return response;
}};
I ended up fixing this by assigning the original success function to a variable and then calling it after my own code:
var ajaxAdapter = breeze.config.getAdapterInstance('ajax');
ajaxAdapter.requestInterceptor = function (requestInfo) {
var oldSuccessFn = requestInfo.success;
requestInfo.success = function (data, statusText, jqXHR) {
if (data.Message == "Authorization has been denied for this request.") {
signOut();
} else {
var result;
oldSuccessFn.call(result, data, statusText, jqXHR);
return result;
}
},

HTTP Request Referer in Meteor Iron Router

I have a server side route in my Meteor app where I can get, for instance, the client's IP:
this.route('foo', {
where: 'server',
path: '/bar',
action: function () {
var ip = context.request.connection.remoteAddress;
}
});
How can I access the referer field? Do I need to use Meteor Headers?
You can directly access the connect request object, which has the headers:
this.request.headers['referer']
Like this:
Router.map(function () {
this.route('foo', {
where: 'server',
path: '/bar',
action: function () {
console.log("All headers:", this.request.headers);
console.log("Referer:", this.request.headers['referer']);
}
})
});
I just had the same problem and after some more digging I figured out if the source page was secure (HTTPS) the browser will not send the referer.
As well if the source document is on the local computer a referer is not available. That fooled me for a while as I simply created a test.html on the Desktop for testing...
So the code in my route for blocking direct requests to this route from other websites looks like this now:
action: function () {
var self = this;
var host = self.request.headers.host;
var referer = self.request.headers.referer;
var regex = new RegExp("^http(?:s)?://" + host);
if(typeof self.request.headers.referer !== "undefined" && !regex.test(referer)) {
Meteor.log.error("Access blocked from " + referer);
self.response.statusCode = 403;
self.response.end(Handlebars.templates['403']());
return;
}
}
If the referer is set, it has to match the current hostname.
you can do document.referrer to get that information
alternatively you can use History API:
history.go(-1);

Jquery Ajax, not working in Internet explorer

I'm trying to do some jQuery ajax and it works in Firfox and Chrome, but not in internet explorer 9.
The final code will have to go across sub-domains, and this doesn't work in ie with the default transport.
So I'm trying to create a custom transport to use in internet explorer
Method 1
$.ajaxTransport("+*", function (options, originalOptions, jqXHR) {
if (jQuery.browser.msie && window.XDomainRequest) {
var xdr;
return {
send: function (headers, completeCallback) {
// Use Microsoft XDR
xdr = new XDomainRequest();
xdr.open("get", options.url);
xdr.onload = function () {
if (this.contentType.match(/\/xml/)) {
var dom = new ActiveXObject("Microsoft.XMLDOM");
dom.async = false;
dom.loadXML(this.responseText);
completeCallback(200, "success", [dom]);
} else {
completeCallback(200, "success", [this.responseText]);
}
};
xdr.ontimeout = function () {
completeCallback(408, "error", ["The request timed out."]);
};
xdr.onerror = function () {
completeCallback(404, "error", ["The requested resource could not be found."]);
};
xdr.send();
},
abort: function () {
if (xdr) xdr.abort();
}
};
}
});
I've created a simple sample page to demonstrate the first technique here:
http://services.whygo.net/sendAjax.htm
Please note if you use the custom transport the normal transport will then fail unless you refresh
The idea comes from here:
http://forum.jquery.com/topic/cross-domain-ajax-and-ie#14737000002203097
This give no error message other than 'error' inside the 'error' method called on $ajax, when it fails. I do get a 405 Method not allowed on the 'Network' tab of if dev tools, but the server side stuff does execute.
Method 2
I have also tried another method as described here:
Cross-subdomain AJAX works in Chrome, not IE
if ('XDomainRequest' in window && window.XDomainRequest !== null) {
// override default jQuery transport
jQuery.ajaxSettings.xhr = function() {
try { return new XDomainRequest(); }
catch(e) { }
};
}
This can be found here:
http://www.whygo.net/sendAjax2.html
On this one I actually get 200 codes on the 'network' tab of ie dev tools, but doesn't call the 'error' or the 'success' pararm of $ajax.
If I put a timeout on this second one, then it returns to the 'error' function with a message of 'timeout'.
Here's the solution I went with after about a day of struggling with this inconsistency...
// new method as to not overwrite jQuery's defaults
var cors = (window.XDomainRequest) ? function(url, callback) {
var xdr = new XDomainRequest();
xdr.open('get', url);
xdr.onload = function() { callback(xdr.responseText); }
xdr.send();
} : $.get; // else, use jQuery's method
Use...
cors(url, function(msg) { alert(msg); }); // pretty well same as $.get
Copy and paste, this of course doesn't serve all purposes, but it's a start and it works.
On the http://services.whygo.net/sendAjax2.html page, I see that you've got the expected dataType of the AJAX response coming back from the server as JSON, but the response actually comes back as a plain text string ("Email successfully sent.").
Perhaps you could try commenting out dataType and let jQuery figure out what type of response comes back.

Why is my node static file server dropping requests?

I have a standard node.js static file server that I want to use to serve normal html, js, css, and jpg files in the same directory (ie- a typical HTML5 single page app). I would expect that the node server can handle this properly. What I see is different.
The index.html file is served, but then subsequent requests are dropped (ie- they never make it to the server). In my chrome dev tools, I see things like this:
GET http://projectcoho.cloudfoundry.com/css/coho.css http://projectcoho.cloudfoundry.com/:7
GET http://projectcoho.cloudfoundry.com/sencha-touch/sencha-touch-debug.js http://projectcoho.cloudfoundry.com/:8
GET http://projectcoho.cloudfoundry.com/coho-debug.js http://projectcoho.cloudfoundry.com/:8
But, these resources exist on the server and you can reach them if you enter their URL directly. And for these requests, my callback in app.js is never invoked (I can tell this because console.log is never called for these files.
Here is the app.js file:
var path = ".";
var port = process.env.VCAP_APP_PORT || 3000;;
var file = new(static.Server) (path, {
cache: 600
});
mime.define({
'text/css': ['css'],
'text/javascript': ['js'],
'image/jpeg': ['jpg', 'jpeg']
});
http.createServer(function (request, response) {
var uri = url.parse(request.url).pathname;
var filename = libpath.join(path, uri);
console.log("URI: " + request.url + " , filename: " + filename);
libpath.exists(filename, function (exists) {
console.log("Serving " + filename);
if (!exists) {
console.log("Not found");
response.writeHead(404, {
"Content-Type": "text/plain"
});
response.write("404 Not Found\n");
response.end();
return;
}
if (fs.statSync(filename).isDirectory()) {
filename += '/index.html';
}
var type = mime.lookup(filename);
file.serveFile(filename, 200, {'content-type' : type}, request, response);
});
}).listen(port);
What am I missing here?
I am using node v0.6.15
In the end, the answer was that my cache.manifest file was incorrect. The client application was looking for resources in a cache, but the didn't exist. When I corrected the manifest, things started working.

Express / NodeJS Can't send headers after they are sent caused by http requests

First time working with NodeJS (yes, it's awesome) and also using Express as well. Got the web app / service working great but I run in to problems when trying to make more than one http request. Here's a video of how the app causes 2 http requests - http://screencast.com/t/yFKdIajs0XD - as you can see I click on 'articles' it loads an rss feed, then click videos and it loads a youtube feed - both work just fine but after the second call is made it throws an exception. I get the following when I attempt two separate http requests using node's http module:
http.js:527
throw new Error("Can't set headers after they are sent.");
^
Error: Can't set headers after they are sent.
at ServerResponse.<anonymous> (http.js:527:11)
at ServerResponse.setHeader (/Users/rickblalock/node/auti_node/node_modules/express/node_modules/connect/lib/patch.js:47:22)
at /Users/rickblalock/node/auti_node/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:72:19
at [object Object].<anonymous> (fs.js:107:5)
at [object Object].emit (events.js:61:17)
at afterRead (fs.js:878:12)
at wrapper (fs.js:245:17)
Sample code provided here:
Using my controller module to render the request - http://pastie.org/2317698
One of the tabs (article tab) - the video code is identical minus referencing a video feed: http://pastie.org/2317731
try using the "end" event not "data" like this:
var data = "";
app.get('/', function(req, res){
var options = {
host: 'http://www.engadget.com',
path: '/rss.xml',
method: 'GET'
};
if (data === "") {
var myReq = http.request(options, function(myRes) {
myRes.setEncoding('utf8');
myRes.on('data', function(chunk) {
console.log("request on data ");
data += chunk;
});
myRes.on('end', function () {
console.log("request on END");
res.render('index', {
title: 'Express',
data: data
});
});
});
myReq.write('data\n');
myReq.end();
}
else {
res.render('index', {
title: 'Express',
data: data
});
}
});
old answer
i also think that this is the culprit:
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function(chunk) {
parseArticle(chunk);
});
});
req.write('data\n');
req.end();
the first line is async so everything inside the callback is called after you do req.write() and req.end()
put these two lines into the callback.

Resources