必须设为 application/octet-stream 才能强制下载,因其明确告知浏览器“原始二进制流,不渲染、只下载”;其他类型如 text/plain 或留空易被内嵌显示,且非标准类型如 application/force-download 不被广泛支持。

Content-Type 必须设为 application/octet-stream 才能强制下载
PHP 8.2 没有新增或废弃 header() 的行为,但浏览器(尤其是 Chrome 120+、Safari 17+)对 MIME 类型更严格:若 Content-Type 是 text/plain、application/json 或留空,即使加了 Content-Disposition: attachment,仍可能内嵌显示或报错。唯一稳妥的选择是 application/octet-stream——它明确告诉浏览器“这是原始二进制流,别猜,别渲染,直接存”。
不推荐用 application/force-download:它不是标准 MIME 类型,PHP 官方文档未收录,Nginx/Apache 也不识别,部分代理会丢弃该头。
-
Content-Type: application/octet-stream是通用兜底方案,适用于 PDF、ZIP、DOCX、MP4 等任意文件 - 若你明确知道类型(如
image/png),也可用,但下载行为仍完全依赖Content-Disposition,不能省略 - 绝对不要用
text/html或text/plain,哪怕文件内容真是纯文本——浏览器会直接渲染,用户看不到下载框
中文文件名必须用 filename*=UTF-8'' 编码,不能只靠 rawurlencode()
只写 filename="中文.pdf" 在 Safari 和旧版 Android 浏览器里大概率乱码或截断成 “?.pdf”。PHP 8.2 下必须用 RFC 5987 标准的 filename* 语法,且需配合 rawurlencode() 处理编码。
正确写法示例:
header('Content-Disposition: attachment; filename="report.pdf"; filename*=UTF-8\'\''.rawurlencode('销售报表.pdf'));
- 前半段
filename="report.pdf"是兼容 fallback,给不支持filename*的老客户端(如 IE11)用 - 后半段
filename*=UTF-8\'\'xxx中的两个单引号之间必须是rawurlencode()编码后的 UTF-8 字节序列 - 注意:
rawurlencode()不等于urlencode()—— 后者把空格转成+,而rawurlencode()转成%20,这是 RFC 强制要求
Content-Length 缺失会导致 iOS Safari 拒绝下载或卡在 99%
PHP 8.2 默认启用 output_buffering,如果没显式调用 ob_clean() 或 flush(),Content-Length 可能被缓冲层干扰,导致 header 发送延迟或值错误。iOS Safari 会校验这个值,一旦不匹配就中断连接。
- 务必用
filesize($filePath)获取真实字节数,别手写或估算 - 大文件(>100MB)慎用
readfile(),改用fopen()+fread()分块输出,并在每块前调用flush() - 设置超时:用
set_time_limit(0)防止脚本中途终止;但也要注意 Web 服务器(如 Nginx 的proxy_read_timeout)是否同步放宽
PHP 8.2 下容易被忽略的三个安全细节
很多 PHP 文件下载代码在本地测试正常,上线后出问题,根源常在这三处:
- 路径遍历漏洞:用户传入
?file=../../etc/passwd,必须用basename($userInput)或realpath($filePath)校验是否落在白名单目录内,不能只靠str_replace('../', '', $input) - 输出缓冲残留:即使调用了
ob_end_clean(),某些框架(如 Laravel)或 Composer 包可能提前开启缓冲,建议在header()前加while (ob_get_level()) ob_end_clean(); - Web 服务器覆盖:Apache 的
AddType或 Nginx 的types块可能强行重写Content-Type,可在响应头中加X-Debug-Header: set验证最终发出的头是否被篡改
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











