10

通过 node.js 模块和通过 XMLHttpRequest 发送的 HTTPS 请求有什么区别?

我正在尝试向亚马逊 aws 发送一个 HTTPS GET 请求以从 javascript (XMLHttpRequest) 获取安全令牌,但它总是失败并显示“ Access-Control-Allow-Origin 不允许来源http://my_ip ”,但如果我通过 node.js 模块发送相同的 HTTPS GET 请求它工作正常。

我对此感到困惑,因为如果服务器确实支持 CORS,来自任何地方的任何请求都应该失败,但它通过 node.js,而不是通过 XMLHttpRequest。

这失败了

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);
});

这工作

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);
});

谁能解释我这是如何工作的?

4

3 回答 3

11

浏览器受Same Origin Policy约束。Node.js 不是。

也就是说,浏览器只允许脚本通过 XHR 向与加载脚本的页面所在域相同的站点发出 HTTP 请求。然而,Node.js 将允许对任何域的 HTTP 请求。

(浏览器的故事现在更多地涉及 CORS,但这仍然是这里的基本问题。)

编辑-详细说明,既然我已经重新阅读了您的问题:CORS 是一种合作协议。通常,互联网上的服务器将向任何人提供内容;这就是运行 Web 服务器的全部意义所在。除非请求者询问,否则 CORS 与 HTTP 请求无关。如果您有 URL “http://xyz/something”,并且您在浏览器的地址栏中键入它,那么浏览器将毫不犹豫地向该站点发出 HTTP 请求。仅当来自另一个域(不是“xyz”)站点的页面中的某些代码尝试通过 XHR 运行 HTTP 请求时,同源策略(和 CORS)才会发挥作用。在这种情况下,浏览器会询问“xyz”站点的访问权限;默认答案是“否”,但那强加该规则,而不是服务器。

于 2012-06-27T16:59:52.687 回答
2

就是环境的不同。您通常可以在任何地方自由发送任何 HTTP 请求(就像您现在通过向该站点发送请求一样)。

Node.js 代表您执行由您提供的程序,因此可能是受信任的。这就是为什么默认情况下没有限制的原因。如果您希望包含和运行不受信任的代码,您可以添加任意限制 - 只需检查您最喜欢的搜索引擎以查找“Node.js 不受信任的代码”,以了解有关可用沙盒的一些想法。

另一方面,浏览器几乎总是运行不受信任的代码,但代表用户并拥有他所有可能的权限。由于浏览器的环境必须标准化以使所有浏览器以相同的方式工作,因此作者之间商定了一组安全策略,并在他们的浏览器中实现了根据同源策略和后来的CORS控制从 JavaScript 传出的 XHR 连接。浏览器本身控制这些限制,而不是 JavaScript 或远程服务器。如果您也选择另一种语言,您将受到环境施加的完全相同的限制。

于 2012-06-27T17:27:50.923 回答
1

node.js 是一种服务器端语言。不要被 .js 扩展名弄糊涂了。当您不熟悉它时,这总是会引起很多混乱。所以它很像 php 或 C++。您可以在任何地方发送任何请求。访问任何站点(因此是 https 请求)。但在浏览器 javascript 中,这是一种客户端语言。浏览器不允许您从另一台服务器访问页面。假设您在 host.com:80。您只能从 host.com:80/*not host2.com 甚至 something.host.com 访问数据

这不适用于 node.js

于 2012-06-27T17:03:10.073 回答