嗨,我希望用户能够从我的服务器(Windows)下载PDF文件配置了nginx PHP。这是我的nginx.conf (server block)
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
我从这里尝试了一些例子/解决方案,但到目前为止都没有工作。文件很大(每个在250到400 MB之间),每个用户可以下载4个文件。
使用PHP下载部分没有问题,只有nginx配置似乎不工作。未检测到错误日志
好的,这里有几个问题:
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配置应该是这样的:
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 server中,我们需要像这样在别名中设置完整路径:
location /protected_files {
internal;
alias C:/absolute/path/to/project/protected/;
}
请注意,额外的斜杠是需要的(在我的情况下,Windows 7 Pro开发,Windows Server 2008部署)。唯一的问题是,现在我需要测试并发下载,看看服务器资源是否占用。
我是nginx的新手,因为它看起来真的比我从Apache切换更快。谢谢你的启发!我很高兴成为Stackoverflow社区的一员:)