如何创建重写规则以在使用 nginx 下载时即时重命名 PDF 文件?

How to create rewrite rule to Rename PDF file on the fly while Downloading using nginx?

我在允许用户下载 PDF 文件的网站上工作。 每个 PDF 文件都使用随机哈希名称存储在服务器上, 例如

file
768E1F881783BD61583D64422797632A35B6804C.pdf 
is stored in
/usr/share/nginx/html/contents/7/6/8/E/1/768E1F881783BD61583D64422797632A35B6804C.pdf 

现在我可以尝试为用户提供文件的直接位置,但下载后的文件名显示为 768E1F881783BD61583D64422797632A35B6804C.pdf,我想即时重命名文件,我可以实现这个像这样使用 php

<?php
// We'll be outputting a PDF  
header('Content-type: application/pdf');

// It will be called downloaded.pdf  
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf  
readfile('original.pdf');
?> 

参考:Rename pdf file to be downloaded on fly

但我正在寻找 nginx 直接规则的东西,它可以将下载 url 重写为路径并即时重命名。

我该怎么做?

我试过这样的东西。

location ^/download-pdf {
    alias   /usr/share/nginx/html/contents;
if ($request_filename ~ ^.*?/[^/]*?_(.*?\..*?)$)
{
    set $filename ;
}

add_header Content-Disposition 'attachment; filename=$filename';
}

所以如果我将用户发送到这个位置

domain.com/download-pdf/768E1F881783BD61583D64422797632A35B6804C.pdf?title=this.is.test

然后我希望使用 title/filename 作为 this.is.test.pdf

在用户 PC 上下载此文件
/usr/share/nginx/html/contents/7/6/8/E/1/768E1F881783BD61583D64422797632A35B6804C.pdf 

仅使用 nginx 重写规则就可以做到这一点吗?或者我也需要使用 PHP


更新1:

我试过这样使用它

location ^/download-pdf/([0-9A-F])/([0-9A-F])/([0-9A-F])/([0-9A-F])/([0-9A-F])/([0-9A-F]+).pdf$ {
    alias   /usr/share/nginx/basesite/html/contents;
add_header Content-Disposition 'attachment; filename="$arg_title.pdf"'; 
}

但是访问 url 给出了 404 not found 错误。


更新2:

尝试过这个

location ~ /download-pdf {
alias   /usr/share/nginx/html;
rewrite ^/download-pdf/([0-9a-fA-F])/([0-9a-fA-F])/([0-9a-fA-F])/([0-9a-fA-F])/([0-9a-fA-F])/([0-9a-fA-F]+).pdf$ /contents//////.pdf break;
add_header Content-Disposition 'attachment; filename="$arg_title.pdf"'; 
}

仍然收到 404 未找到。

如果我没记错的话,你不能同时使用 aliasrewrite。相反,只需使用位置正则表达式匹配,这些捕获将可用于 add_headeralias 指令:

location ~* /download-pdf/([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F]+)\.pdf$ {
    add_header Content-Disposition 'attachment; filename="$arg_title"';
    alias   /usr/share/nginx/basesite/html/contents//////.pdf;
}

这将匹配这个 URL:

https://www.example.com/download-pdf/768E1F881783BD61583D64422797632A35B6804C.pdf?title=SamplePdf.pdf

并将其映射到此文件路径:

/usr/share/nginx/basesite/html/contents/7/6/8/E/1/768E1F881783BD61583D64422797632A35B6804C.pdf

注意:如果有人想让正则表达式不那么难看,那就去做吧!