问题
Question (see below for longer explanations and things I have tried already) :
Is there a way of having the short URL http://example.com/qf56p9z redirect to the first file found on the server of the form /files/qf56p9z_(.*)
, and having it downloaded on the client with filename = (.*)
? (if possible, without PHP)
Background :
I have a file on server stored in /files/qf56p9z_blahblah.xls
that I would like to be accessible from this short URL :
http://example.com/qf56p9z
(+the same for other thousands of files)
Moreover, I would like that when the user goes to this URL, the file will be downloaded on the client computer with the original filename, i.e. blahblah.xls
.
This may be possible with PHP, I tried things like (this could be easily automated for each of my thousands of files) :
<?php
header('Content-type: ...');
header('Content-Disposition: attachment; filename="blahblah.xls"');
readfile('qf56p9z_blahblah.xls');
?>
But I see two problems with this method :
For each reading of the file by a client, PHP has to load the whole file in memory, and output the new file. This is much more CPU/memory consuming than if apache has just to send the file, without PHP
If one day I host all those files elsewhere (on Amazon S3 for example), the file will have to do this route :
Distant-Hosting (AmazonS3) ==> my server/header modified with PHP ==> client
It is a shame that the data has to do this instead of :
Distant-Hosting (AmazonS3) ==> client
回答1:
You can use a combination of PHP and .htaccess (using mod_rewrite)
Site structure
/var/www/html/files/
: directory that contains your files in{prefix}_{filename}
format/var/www/html/download.php
: PHP script to locate the first file with given prefix/var/www/html/.htaccess
: with 2 mod_rewrite rules for rewriting the download URL
download.php
<?PHP
$files_dir = "files/";
if(isset($_GET['prefix'])){
$files = glob($files_dir.$_GET['prefix']."_*");
if(count($files) > 0) {
$dl = strlen($files_dir);
$pl = strlen($_GET['prefix']);
$fn = substr($files[0], $dl+$pl+1);
header("Location: d/".$_GET['prefix']."/".$fn);
}
}
?>
This selects the first file with the required prefix and redirects to it.
.htaccess
RewriteEngine On
RewriteRule ^(\w+)$ download.php?prefix=$1 [L]
RewriteRule ^d/(.+)/(.+)$ files/$1_$2 [L]
The first rule rewrites the short URL to download.php and the second rule rewrites the URL to the original file location.
This is how it works
- http://example.com/qf56p9z -- .htaccess -> http://example.com/download.php?prefix=qf56p9z
- download.php -- PHP Redirect --> http://example.com/d/qf56p9z/blahblah.xls
- http://example.com/d/qf56p9z/blahblah.xls -- .htaccess --> http://example.com/files/qf56p9z_blahblah.xls
During all the above steps, browser's location bar URL remains the same without any change.
来源:https://stackoverflow.com/questions/26486157/file-with-a-short-url-downloaded-with-original-filename