我有一个应该下载歌曲的页面。下载对我来说在firefox中有效,但在chrome和safari中什么都没发生。。这是我的代码
public function download() {
if (isset($this->request->get['order_download_id'])) {
$order_download_id = $this->request->get['order_download_id'];
} else {
$order_download_id = 0;
}
$download_info = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_download od LEFT JOIN `" . DB_PREFIX . "order` o ON (od.order_id = o.order_id) WHERE o.customer_id = '" . (int)$this->customer->getId(). "' AND o.order_status_id > '0' AND o.order_status_id = '" . (int)$this->config->get('config_download_status') . "' AND od.order_download_id = '" . (int)$order_download_id . "'");
if ($download_info->row) {
$file = DIR_DOWNLOAD . $download_info->row['filename'];
$mask = basename($download_info->row['mask']);
$mime = 'application/octet-stream';
$encoding = 'binary';
if (!headers_sent()) {
if (file_exists($file)) {
header('Pragma: public');
header('Expires: 0');
header('Content-Description: File Transfer');
header('Content-Type: ' . $mime);
header('Content-Transfer-Encoding: ' . $encoding);
header('Content-Disposition: attachment; filename="' . ($mask ? $mask : basename($file)) . '"');
header('Content-Length: ' . filesize($file));
$file = readfile($file, 'rb');
print($file);
} else {
exit('Error: Could not find file ' . $file . '!');
}
} else {
exit('Error: Headers already sent out!');
}
}
}
我尝试了各种不同的方法来实现这一点,但在两个浏览器中都没有发生任何事情。。。任何想法或帮助都将不胜感激。。。
readfile
返回发送的字节数,不需要打印出来。您应该删除线路print($file);
。否则,您将发送比Content-Length
标头指定的字节更多的字节,这将导致一些HTTP客户端丢弃您的答案。
此外,考虑奇怪的文件名,如
"rnLocation: http://evil.comrnrn<script>alert('XSS');</script>
你处理得对吗?
查看附近的语法
header('Content-Disposition: attachment; filename="'.$file_name_with_space. '"');
或者可以是
header("Content-Disposition: attachment; filename='".$file_name_with_space."'" );
这里的游戏只有引号,如果写得正确,它将被视为字符串的一部分,否则将崩溃。
它适用于所有浏览器。IE,FF,Chrome,SAFARI我亲自检查了一下,所以太刺激了。