我正在设置一个设置,其中 Apache 运行 Web 应用程序,而 NginX 提供用户下载的文件。文件应该使用其真实名称下载,而不是使用其存储的名称。真实名称是从数据库中检索的。我不明白为什么我无法强制 NginX 使用其真实名称下载文件。我将以下 php 标头从 Apache 发送到 NginX:
header('Location: ' . "http://nginx.mysite.com:8080/" . $file['upload_id']);
header('Content-type: ' . $this->mime);
header('Content-Disposition: attachment; filename="' . $file['file_name'] . '"');
header('Last-Modified: ' . date('D, d M Y H:i:s \G\M\T' , $this->data_mod));
看起来 NginX 忽略了 content-disposition 标头?还是我的语法有问题?
编辑:输出
curl --head http://…/your/file.ext
如下:
HTTP/1.1 200 OK
Server: nginx/1.0.5
Date: Sat, 16 Feb 2013 14:26:33 GMT
Content-Type: application/octet-stream
Content-Length: 38807550
Last-Modified: Sun, 06 Jan 2013 14:37:36 GMT
Connection: keep-alive
Accept-Ranges: bytes
答案1
nginx 不会仅仅因为标头是从 Apache 返回的就知道它需要返回标头。对 Apache 的请求将返回该标头,但您还告诉客户端从 nginx 获取该文件,并且 nginx 不会接收该标头,也不会知道将其发回,除非您在 nginx 配置中做了一些事情来执行此操作。
这是它现在的工作方式(...
代表与本次讨论不重要的其他标题):
向 Apache 发出请求
GET /your/file.ext HTTP/1.1
Host: apache.mysite.com
...
Apache 的响应
HTTP/1.1 302 Redirect
Location: http://nginx.mysite.com:8080/fileid
Content-Disposition: attachment; filename="filename"
...
当你的 Web 客户端收到此消息时,它基本上被告知要转到其他地方。这将发起一个新请求:
向 nginx 发出请求
GET /fileid HTTP/1.1
Host: nginx.mysite.com
...
nginx 的响应
HTTP/1.1 200 OK
... (no Content-Disposition header)
您需要让 nginx 响应返回Content-Disposition
标头,而不是 Apache/PHP 响应。您有以下几种选择:
- 将 nginx 请求传递给脚本,该脚本将表单转换
fileid
为file.ext
表单,发回Content-Dispotion:
标题并返回数据(这与您的 PHP 脚本非常相似,只是它还需要返回文件数据)。 - 从 nginx请求
file.ext
表单,并配置 nginx 以始终添加Content-Disposition:
带有设置请求filename=
部分的标头。file.ext
- 更新您的 PHP 脚本以在内部代理 nginx 请求,这样
Location:
它就不会返回标头和随后的重定向,而是返回所需的标头,然后从 nginx 内部获取数据并将其转储到客户端。
第二种选择似乎最干净对我来说,但您的设置可能不支持它。