node.js https请求和XMLHttpRequest有什么区别?

10

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

我正在尝试使用 JavaScript(XMLHttpRequest)发送 HTTPS GET 请求,从 Amazon AWS 获取安全令牌,但始终会出现“起源 http://my_ip 不被 Access-Control-Allow-Origin 允许”的错误。但是,如果我通过 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);
});

有人能解释一下这个是如何工作的吗?

3个回答

11

浏览器受同源策略的限制。而Node.js则没有这个限制。

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

(现在浏览器的情况稍微复杂了一些,因为有CORS,但基本问题仍然是同源策略。)

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


具体来说(为了扩展答案并鼓励讨论,使其成为规范答案),SOP的重点是防止恶意代码加载到您的浏览器中,以防止某些网站在您的计算机上运行跟踪广告,其中广告加载一些JavaScript以显示图像(因此您不知道您“被感染”了,因为您看到了图像),然后该代码监视您在页面上输入的每个按键,并将其引用到其主服务器。假设它监视书签(可以在JS中完成)并查看您使用哪个银行?信用卡号码呢? - jcolebrand

2
这是环境上的差异。通常情况下,您可以自由地向任何地方发送HTTP请求(就像您现在向此网站发送请求一样)。
Node.js代表您执行您提供的程序,因此可以认为是受信任的。这就是为什么默认情况下没有限制的原因。如果您希望包含并运行不受信任的代码,则可以添加任意限制-只需检查您喜欢的搜索引擎以获取有关可用沙箱技术的想法即可。
另一方面,浏览器几乎总是运行不受信任的代码,但代表用户并具有所有可能的权限。由于浏览器的环境必须标准化以使所有浏览器以相同的方式工作,因此作者之间达成了一组安全策略,并根据same origin policy和后来的CORS实施了对JavaScript发出的XHR连接的控制。 浏览器本身控制着这些限制,而不是JavaScript或远程服务器。如果选择其他语言,您将面临完全相同的环境限制。

1

node.js是一种服务器端语言。不要被.js扩展名所困惑。当你刚接触时,这经常会引起很多混乱。因此,它很像php或C ++。您可以将任何请求发送到任何地方。访问任何站点(因此是https请求)。但在浏览器JavaScript中,这是一种客户端语言。浏览器不允许您从另一个服务器访问页面。假设您在host.com:80上。您只能从host.com:80 / *而不是host2.com甚至something.host.com访问数据

这不适用于node.js


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接