用PHP和nginx X-Accel-Redirect服务大文件

您好,我希望用户能够从我的服务器(Windows)下载configuration了Nginx PHP的PDF文件。 这是我的nginx.conf(服务器块)

http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.php; } location /download { internal; alias /protected; } } } 

..和PHP文件(标题部分)

 $file = '/download/real-pdf-file.pdf'; //this is the physical file path $filename = 'user-pdf-file.pdf'; //this is the file name user will get header('Cache-Control: public, must-revalidate'); header('Pragma: no-cache'); header('Content-Type: application\pdf'); header('Content-Length: ' .(string)(filesize($file)) ); header('Content-Disposition: attachment; filename='.$filename.''); header('Content-Transfer-Encoding: binary'); header('X-Accel-Redirect: '. $file); 

该文件是从URL调用,如下所示:

 download.php?id=a2a9ca5bd4a84294b421fdd9ef5e438ded7fcb09 

我已经尝试了几个例子/解决scheme,但迄今为止没有工作。 该文件很大(每个在250到400 MB之间),每个用户将能够下载4个文件。

使用PHP下载部分没有问题,只有看起来不起作用的nginxconfiguration。 没有检测到错误日志。

好的 – 这里有几个问题:

1)根据nginx开发人员的说法,在某个位置放置根是一个糟糕的想法 。

2)用于告诉Nginx这个内部重定向的内部URL不应该暴露给用户。

3)我看不到你的download.php文件从哪里提供,所以我改变了你的根目录块来使用try_files,所以对/download.php的请求将由该文件而不是index.php提供。

您的项目应按以下方式进行布局:

 project\ html - this is the root of your website protected - this directory is not accessible directly 

而你的Nginx conf应该是这样的:

 http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; root /path/to/project/html; location / { try_files $uri /index.php?$args; } location /protected_files { internal; alias /path/to/project/protected; } } } 

不要重复使用相同的名字来表示不同的东西,因为这很混乱。 我已经改变了他们,所以现在protected只是指实际的物理目录,其中包含你想要服务的文件。 protected_files只是一个允许Nginx匹配来自x-accel头部的请求的字符串。

唯一需要改变你的PHP代码的是使用正确的字符串来允许Nginx获取内部位置:

 $aliasedFile = '/download/real-pdf-file.pdf'; //this is the nginx alias of the file path $realFile = '/path/to/project/protected/real-pdf-file.pdf'; //this is the physical file path $filename = 'user-pdf-file.pdf'; //this is the file name user will get header('Cache-Control: public, must-revalidate'); header('Pragma: no-cache'); header('Content-Type: application\pdf'); header('Content-Length: ' .(string)(filesize($realFile)) ); header('Content-Disposition: attachment; filename='.$filename.''); header('Content-Transfer-Encoding: binary'); header('X-Accel-Redirect: '. $aliasedFile); exit(0); 

根据Danack的建议和解决方案以及Carsten的一些说明,我发现在Windows Serve中,我们需要在别名中设置完整路径,如下所示:

 location /protected_files { internal; alias C:/absolute/path/to/project/protected/; } 

请注意,额外的正斜杠是需要的(在我的情况下,Windows 7专业版开发,Windows server 2008的部署)。 唯一的问题是现在我需要测试并发下载,看看服务器资源是否被占用。

我是nginx的新手,因为我从Apache切换起来似乎更快。 感谢小伙子的启迪! 我很高兴成为Stackoverflow社区的一部分:)