【问题标题】:Is the File Transfer code correct in my PHP?我的 PHP 中的文件传输代码是否正确?
【发布时间】:2011-09-27 09:50:47
【问题描述】:

我有这个page,它应该是一首歌曲的下载。下载对我来说在 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 的返回值——你已经发送了内容的长度,这是出乎意料的(另外它会破坏接收者的文件结束)。
  • 如果你删除底部的重定向,你会得到一个文件吗?我对 IE 了解不够,但它可能只是在处理响应正文之前读取标头并跟随重定向流。
  • HTTP 中没有内容传输编码。请删除它。

标签: php file download content-type content-disposition


【解决方案1】:

readfile返回发送的字节数,不需要打印出来。您应该删除行print($file);。否则,您发送的字节数将超过 Content-Length 标头指定的字节数,这将导致一些 HTTP 客户端放弃您的答案。

另外,考虑奇怪的文件名,例如

"\r\nLocation: http://evil.com\r\n\r\n<script>alert('XSS');</script>

你处理得对吗?

【讨论】:

【解决方案2】:

查看附近的语法

header('Content-Disposition: attachment; filename="'.$file_name_with_space. '"');

也可以

header("Content-Disposition: attachment; filename='".$file_name_with_space."'" );

这里的游戏只有引号,如果写得正确,它将被视为字符串的一部分,否则会崩溃。

它适用于所有浏览器。 IE, FF, Chrome, SAFARI 我亲自检查过所以goahead。

【讨论】:

  • 请注意,这不适用于非 ASCII 字符;请参阅 RFC 6266。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-23
  • 2013-12-23
  • 2019-07-02
相关资源
最近更新 更多