Nginx X-Accel-Redirect不能和node.js一起使用,如何解决?

4

我正在尝试使用Node.js支持的nginx设置授权文件访问。但是不知为何,所有的示例都对我无效。我试图从/data/private/files服务文件。

我的nginx配置如下:

...
server {
    listen 4000;
    server_name localhost;

    location / {
        proxy_pass http://127.0.0.1:3000/;
    }

    location /files {
        root /data/private;
        internal;
}  

我的Node服务器.js文件:

var http = require('http');
http.createServer(function (req, res) {
  console.log(req.url);
  res.end('works');
}).listen(3000);

当我请求http://localhost:4000/xyz时,请求被正确地传递到了node。但是当我请求http://localhost:4000/files/test.jpg时,我只得到了一个404错误,并且没有传递到node。我做错了什么?当我注释掉internal时,test.jpg直接由nginx正确地提供服务,所以我认为路径是正确的?
我很确定在之前的某个服务器上,也许是使用不同的node和nginx版本,我曾经让它工作过。我尝试过nginx 1.6.0和1.2.6,node v0.10.21。我还添加了所有proxy_set_header和proxy_pass选项,这些都是在所有示例中找到的,但是都没有起作用。我现在在基于Vagrant的Ubuntu VM上运行它,但在Mac上也无法工作。
我知道我必须通过res.setHeader("X-Accel-Redirect", req.url);设置头文件,但这不是问题,因为我甚至没有进入可以在node中设置所需头文件的阶段。
1个回答

7
您对internalX-Accel-Redirect的工作原理存在误解。
主要思想是您访问某个被代理到应用程序的URL,然后应用程序决定您是否有权访问文件。如果是前一种情况,它将响应带有受保护URL(具有internal属性)的X-Accel-Redirect
因此,您应该访问其他URL,例如http://localhost:4000/get/files/test.jpg,您的应用程序可能类似于此:
var http = require('http');
http.createServer(function (req, res) {
  if (req.url.indexOf('/get/files/') == 0) {
    if (userHasRightToAccess()) {
      res.setHeader('X-Accel-Redirect', res.url.slice(4));
      res.end('');
    } else {
      // return some error
    }
  } else {
    console.log(req.url);
    res.end('works');
  }
}).listen(3000);

非常感谢!这很有道理,我在阅读更多相关内容的过程中有些迷失了。我陷入了请求和路径必须匹配的想法中。我花了几个小时才解决问题,再次感谢! - ti2m
嘿,Alexey,我正在客户端ajax端使用它来访问nginx服务器在内部重定向后返回的文件:http.onreadystatechange = function() { if(http.readyState == 4 && http.status == 200) { localStorage.setItem("Authorization",http.getResponseHeader("Authorization")); window.document.write(http.responseText); } 但是对我来说它不起作用。我将页面HTML内容作为响应主体的一部分获取,但它会在当前标签页中打开页面。你能帮忙解决一下吗? - gonephishing
@gonephishing,nginx的内部重定向与ajax无关。请创建新问题。 - Alexey Ten

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