What is the difference between a HTTPS request sent via node.js module and via XMLHttpRequest?
I am trying to send a HTTPS GET request to amazon aws to get a security token from javascript (XMLHttpRequest) and it always fails with "Origin http://my_ip is not allowed by Access-Control-Allow-Origin", but if I send same HTTPS GET request via a node.js module it works fine.
I am confused of this because if server does support CORS, any request from any where should fail, but it goes through via node.js, but not via XMLHttpRequest.
This FAILS
var url_ = "/?Action=GetSessionToken" +
"&DurationSeconds=3600" +
"&AWSAccessKeyId=XXXXXXXXXXXXXXX" +
"&Version=2011-06-15" +
"&Timestamp=" + encode(timestamp) +
"&Signature=" + encode(hash) +
"&SignatureVersion=2&SignatureMethod=HmacSHA256";
// Simple GET request
$.get(url_, function(data) {
alert("response: " + data);
});
This WORKS
var https = require('https');
var options = {
host : 'sts.amazonaws',
method : 'GET',
path : '/?Action=GetSessionToken' +
'&DurationSeconds=3600' +
'&AWSAccessKeyId=XXXXXXXXXXXXXX' +
'&Version=2011-06-15' +
'&' + timestamp +
'&' + signature +
'&SignatureVersion=2&SignatureMethod=HmacSHA256'
};
https.get(options, function(res) {
res.on('data', function(d) {
process.stdout.write(d);
});
}).on('error', function(e) {
console.error(e);
});
Can anyone explain me how this works?
What is the difference between a HTTPS request sent via node.js module and via XMLHttpRequest?
I am trying to send a HTTPS GET request to amazon aws to get a security token from javascript (XMLHttpRequest) and it always fails with "Origin http://my_ip is not allowed by Access-Control-Allow-Origin", but if I send same HTTPS GET request via a node.js module it works fine.
I am confused of this because if server does support CORS, any request from any where should fail, but it goes through via node.js, but not via XMLHttpRequest.
This FAILS
var url_ = "https://sts.amazonaws.com/?Action=GetSessionToken" +
"&DurationSeconds=3600" +
"&AWSAccessKeyId=XXXXXXXXXXXXXXX" +
"&Version=2011-06-15" +
"&Timestamp=" + encode(timestamp) +
"&Signature=" + encode(hash) +
"&SignatureVersion=2&SignatureMethod=HmacSHA256";
// Simple GET request
$.get(url_, function(data) {
alert("response: " + data);
});
This WORKS
var https = require('https');
var options = {
host : 'sts.amazonaws.com',
method : 'GET',
path : '/?Action=GetSessionToken' +
'&DurationSeconds=3600' +
'&AWSAccessKeyId=XXXXXXXXXXXXXX' +
'&Version=2011-06-15' +
'&' + timestamp +
'&' + signature +
'&SignatureVersion=2&SignatureMethod=HmacSHA256'
};
https.get(options, function(res) {
res.on('data', function(d) {
process.stdout.write(d);
});
}).on('error', function(e) {
console.error(e);
});
Can anyone explain me how this works?
Share Improve this question edited Jun 17, 2016 at 11:29 Nico 1,5941 gold badge23 silver badges36 bronze badges asked Jun 27, 2012 at 16:58 pbathalapbathala 1,4102 gold badges19 silver badges39 bronze badges3 Answers
Reset to default 12The browser is constrained by the Same Origin Policy. Node.js is not.
That is, a browser will let scripts make HTTP requests via XHR only to sites in the same domain as that of the page that loaded the script. Node.js, however, will allow HTTP requests to any domain.
(The browser story is slightly more involved now with CORS, but it's still the basic issue here.)
edit — to elaborate, now that I've re-read your question: CORS is a cooperative protocol. A server on the Internet will serve content to anybody, generally; that's the whole point of running a web server. CORS has nothing to do with HTTP requests unless the requestor asks about it. If you have URL "http://x.y.z/something", and you type that into your browser's address bar, then the browser will unhesitatingly issue the HTTP request to that site. The Same Origin Policy (and CORS) only comes into play when some code in a page from a site in another domain (not "x.y.z") attempts to run an HTTP request via XHR. In that case, the browser asks the "x.y.z" site about access; the default answer is "no", but that's the browser imposing that rule, not the server.
node.js is a server side language. Donot be confused by the .js extension. That always causes a hell lot of confusion when you're new to it. So its a lot like php, or C++. YOu can send whatever request wherever you want. Access any site(the https request hence). But in Browser javascript, this is a client side language. Browser won't allow you to access a page from another server. Say you are at host.com:80. You can only acess data from host.com:80/*not host2.com or even something.host.com
This ddoesn't apply to node.js
It is difference in environment. You can usually freely send any HTTP request anywhere (just as you're doing right now by sending request to this very site).
Node.js executes on your behalf program provided by you and thus, presumably, trusted. That's why there's no restrictions by default. You can add arbitrary restrictions if you expect to include and run untrusted code - just check your favorite search engine for "Node.js untrusted code" for some idea on sandboxing available.
Browser, on the other hand, almost always run untrusted code, but on behalf of user and with all his possible permissions. Since browser's environment must be standartized for all browsers to work in same way, a set of security policies was agreed upon between authors and they implemented in their browsers control of XHR connections outgoing from JavaScript according to same origin policy and later, CORS. Browser itself controls those limitations and not JavaScript or remote server. You'll have exactly same restrictions imposed by environment if you chose another language as well.