强制浏览器下载文件需严格设置三个 header:关闭缓存、Content-Type 为 application/octet-stream、Content-Disposition 指定 rawurlencode 编码的附件名,且须在任何输出前调用并避免 BOM、空格、session 启动等干扰。

PHP 中用 header 强制浏览器下载文件的关键设置
直接生效的核心是三组 header:关闭缓存、声明内容类型为 application/octet-stream、用 Content-Disposition 指定附件名。漏掉任意一个,都可能导致文件被打开而非下载,或在某些浏览器(如 Chrome 119+)中静默失败。
必须设置的三个 header 及其顺序和参数细节
顺序不能颠倒,且需在任何输出(包括空格、BOM、echo)之前调用:
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"');其中:
-
Cache-Control避免代理或浏览器缓存旧响应,no-store比no-cache更严格,推荐同时使用 -
Content-Type必须是无关联类型的二进制流,application/octet-stream最稳妥;不要用text/plain或推测 MIME 类型,否则 Safari 可能直接渲染 -
filename值必须用rawurlencode()编码(不是urlencode()),否则中文名在 Firefox 和 Edge 中会乱码;双引号不可省略
下载前必须检查的常见错误点
这些错误不会报 PHP 错误,但会导致 header 失效:
电子手机配件网站源码是一个响应式的织梦网站模板,软件兼容主流浏览器,且可以在PC端和手机端中进行浏览。模板包含安装说明,并包含测试数据。本模板基于DEDECms 5.7 UTF-8设计,需要GBK版本的请自己转换。模板安装方法:1、下载最新的织梦dedecms5.7 UTF-8版本。2、解压下载的织梦安装包,得到docs和uploads两个文件夹,请将uploads里面的所有文件和文件夹上传到你的
- 脚本开头存在 UTF-8 BOM(尤其 Windows 编辑器保存时默认添加),用
hexdump -C your.php | head检查前几字节是否为ef bb bf - 在
header()前有echo、var_dump()、甚至换行或空格 - 启用了
output_buffering但未显式ob_end_clean(),导致缓冲区已有内容 - 使用了
session_start()且 session 文件已写入,此时 PHP 自动发送Set-Cookie,破坏 header 流程
完整可运行的最小示例(含安全处理)
以下代码假设文件路径已校验,不接受用户直传路径:
$file_path = '/var/www/files/report.pdf';
$filename = '2024年度报告.pdf';
if (!is_file($file_path) || !is_readable($file_path)) {
http_response_code(404);
exit;
}
ob_end_clean();
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($file_path));
header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"');
readfile($file_path);
exit;注意:Content-Length 虽非强制,但加上后能避免 Chrome 下载进度条卡在 99%,也方便断点续传支持。










