如何在Nginx上结合try_files和sendfile?

如果存在的话,我需要Nginx提供文件相关的文件,如果不存在,则回退到上游服务器。 这可以通过如下方式来完成:

server { listen 80; server_name localhost; location / { root /var/www/nginx/; try_files $uri @my_upstream; } location @my_upstream { internal; proxy_pass http://127.0.0.1:8000; } } 

很公平。 问题是,我的上游没有直接提供URI的内容,而是将X-Accel-Redirect返回到相对于文档根目录的位置(即时生成此文件):

 % curl -I http://127.0.0.1:8000/animals/kitten.jpg__100x100__crop.jpg HTTP/1.0 200 OK Date: Mon, 26 Nov 2012 20:58:25 GMT Server: WSGIServer/0.1 Python/2.7.2 X-Accel-Redirect: animals/kitten.jpg__100x100__crop.jpg Content-Type: text/html; charset=utf-8 

显然,这应该工作。 但问题是,Nginx尝试从一些内部的默认文档根目录来提供这个文件,而不是使用location块中指定的文件:

 2012/11/26 18:44:55 [error] 824#0: *54 open() "/usr/local/Cellar/nginx/1.2.4/htmlanimals/kitten.jpg__100x100__crop.jpg" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /animals/kitten.jpg__100x100__crop.jpg HTTP/1.1", upstream: "http://127.0.0.1:8000/animals/kitten.jpg__100x100__crop.jpg", host: "127.0.0.1:80" 

我如何强制Nginx提供相对于正确的文档根目录的文件? 根据XSendfile文档 ,返回的path应该是相对的,所以我的上游正在做正确的事情。

你需要在server下有root指令,而不是在location下。 这是最常见的nginxconfiguration错误之一 。

您的后端会生成不正确的X-Accel-Redirect标头:URI的path部分必须以/开头(请参阅RFC 3986)。