我尝试创建一些代码,以便用户可以在没有右键单击并使用Save as...
的情况下在opencart中下载图像,但在我创建此代码并下载图像后,尝试打开图像说图像已损坏
<form action="download.php" method="post" >
<input type="text" name="file" value="<?php echo $image['popup']; ?>" />
<input type="submit" value="download" />
</form>
的download.php
<?php
$file= $_POST["file"];
header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header ("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-type: application/pdf');
header('Content-type: image/jpg');
header('Content-type: image/gif');
header('Content-type: image/png');
readfile('$file');
?>
答案 0 :(得分:3)
您当前的问题是,当使用单引号时,$file
将不会被解析,而是按字面意思理解。使用双引号或无引号:
readfile($file);
其他观察:
为什么要发送五种不同的内容类型?这没有意义。您应该检测文件的类型并发送相应的图像标题(如果您只想提供可下载的资源,则只发送application/octet-stream
,而不是尝试在浏览器中显示它。)
您应该检查$file
是否实际指向您要允许下载的文件之一。如果没有检查,攻击者就可以通过这种方式从您的站点获取任何文件,包括配置文件。
答案 1 :(得分:0)
您无法多次定义内容类型。通过文件扩展名确定内容类型,并包含正确的内容类型。
除此之外,请使用:
readfile($file);
不需要报价。编辑:使用引号它甚至不起作用,但它会尝试打开名为$ file
的文件名答案 2 :(得分:0)
您发送了多个Content-Type标头?这是错的。
您必须通过文件的扩展名(.jpg,.pdf,...)确定Content-Type,然后发送相应的标题。
以下是我最近完成的下载脚本片段。
$fileName = $_POST['file']; // or whatever
$file = 'someDirectory/' . $fileName; // full path of the file, could also be absolute
$fileLen = filesize($file);
$ext = strtolower(substr(strrchr($fileName, '.'), 1));
switch($ext) {
case 'txt':
$cType = 'text/plain';
break;
case 'pdf':
$cType = 'application/pdf';
break;
case 'exe':
$cType = 'application/octet-stream';
break;
case 'zip':
$cType = 'application/zip';
break;
case 'doc':
$cType = 'application/msword';
break;
case 'xls':
$cType = 'application/vnd.ms-excel';
break;
case 'ppt':
$cType = 'application/vnd.ms-powerpoint';
break;
case 'gif':
$cType = 'image/gif';
break;
case 'png':
$cType = 'image/png';
break;
case 'jpeg':
case 'jpg':
$cType = 'image/jpg';
break;
case 'mp3':
$cType = 'audio/mpeg';
break;
case 'wav':
$cType = 'audio/x-wav';
break;
case 'mpeg':
case 'mpg':
case 'mpe':
$cType = 'video/mpeg';
break;
case 'mov':
$cType = 'video/quicktime';
break;
case 'avi':
$cType = 'video/x-msvideo';
break;
//forbidden filetypes
case 'inc':
case 'conf':
case 'sql':
case 'cgi':
case 'htaccess':
case 'php':
case 'php3':
case 'php4':
case 'php5':
exit;
default:
$cType = 'application/force-download';
break;
}
$headers = array(
'Pragma' => 'public',
'Expires' => 0,
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Cache-Control' => 'public',
'Content-Description' => 'File Transfer',
'Content-Type' => $cType,
'Content-Disposition' => 'attachment; filename="'. $fileName .'"',
'Content-Transfer-Encoding' => 'binary',
'Content-Length' => $fileLen
);
foreach($headers as $header => $data)
header($header . ': ' . $data);
@readfile($file);
答案 3 :(得分:0)
$mimeInfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($mimeInfo, $_FILES['files']['tmp_name']);
将帮助您检测与
一起使用的mimetype header('Content-Type: '.$this->_mime_type);
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));