在我的函数中,我保存了从base64字符串解码的图像:
function saveImage(){
//magic...
define('UPLOAD_DIR', '../webroot/img/');
$base64string = str_replace('data:image/png;base64,', '', $base64string);
$base64string = str_replace(' ', '+', $base64string);
$data = base64_decode($base64string);
$id = uniqid();
$file = UPLOAD_DIR.$id.'.png';
$success = file_put_contents($file, $data);
}
上述功能正常运行,图像将保存并且不会在指定的文件夹中损坏。
在下一个功能中,我现在试图强制将图像下载给用户:
function getChart($uniqid= null){
if($uniqid){
$this->layout = null;
header("Content-type: image/png");
header("Content-Disposition:attachment;filename='".$uniqid.".png'");
readfile('../webroot/img/'.$uniqid.'.png');
exit;
} else exit;
}
从服务器下载的图像已损坏,无法显示。在文本编辑器中打开下载的文件后,我注意到在最顶部添加了一个新的行字符。删除字符并保存文件后,它会正确打开并正确显示。
我该如何解决这个问题?
答案 0 :(得分:1)
header("Content-length: $file_size")
此标题告诉浏览器文件的大小。有些浏览器需要它才能正确下载文件。无论如何,这是一个很好的方式来告诉文件有多大。这样,下载文件的任何人都可以预测下载需要多长时间。
header("Content-type: $file_type")
此标题告诉浏览器它尝试下载哪种文件。
header("Content-Disposition: attachment; filename=$file_name");
这告诉浏览器以指定的名称保存此下载的文件。如果您不发送此标头,浏览器将尝试使用脚本名称保存文件。
但是您需要使用flush();
或在您的情况下使用ob_flush();
在第一个出口正上方刷新缓冲区;
答案 1 :(得分:1)
在您实际打开下载的文件之前,您所描述的内容可能会隐藏多个问题。
相反,使代码更加健壮并检查前置条件,如果已经发送了头文件,则清除任何可能的现有输出缓冲区,如果不可能则给出错误:
function getChart ($uniqid = null) {
if (!$uniqid) exit;
$this->layout = null;
if (headers_sent()) throw new Exception('Headers sent.');
while (ob_get_level() && ob_end_clean());
if (ob_get_level()) throw new Exception('Buffering is still active.');
header("Content-type: image/png");
header("Content-Disposition:attachment;filename='".$uniqid.".png'");
readfile('../webroot/img/'.$uniqid.'.png');
exit;
}
答案 2 :(得分:0)
编辑(强行下载):
function getChart($uniqid= null){
if($uniqid){
$image = $uniqid;
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=" . $image);
header("Content-Type: image/jpg");
header("Content-Transfer-Encoding: binary");
readfile($image);
} else exit;
}
getChart("060620121945.jpg");
试试这个(仅用于渲染图像):
function getChart($uniqid= null){
if($uniqid){
$mime_type = "image/png";
$content = file_get_contents('../webroot/img/'.$uniqid.'.png');
$base64 = base64_encode($content);
return ('data:' . $mime_type . ';base64,' . $base64);
} else exit;
}
答案 3 :(得分:0)
在致电readfile
之前检查您是否输出了某些内容:
// add ob_start() at the very top of your script
function getChart($uniqid= null){
echo strlen(ob_get_clean()); die(); // if it's not 0 then you are definetly echoing something
if($uniqid){
$this->layout = null;
header("Content-type: image/png");
header("Content-Disposition:attachment;filename='".$uniqid.".png'");
readfile('../webroot/img/'.$uniqid.'.png');
exit;
} else exit;
}
答案 4 :(得分:0)
我多次遇到这个问题。这是我使用的解决方案:
我几乎总是忘记在我的unicode BOM
文件中关闭download.php
编码,这会在下载文件的前面添加内容,从而破坏它。
因此解决方法是关闭unicode BOM
中的download.php
。
答案 5 :(得分:0)
只需使用ob_clean();在readfile()
之前