PHP文件下载代码Safari正常Chrome丢失扩展名问题求助
问题产生原因
- 首先明确一个认知误区:PHP是服务端语言,所有代码均在服务器执行完成后才会将返回值传递给浏览器,不存在"PHP代码在浏览器运行表现不一致"的情况,你遇到的差异本质是不同浏览器对HTTP响应头的解析规则不同导致的。
- 核心问题出在
Content-Disposition响应头的写法不规范:你设置filename参数时没有加双引号包裹,Safari对这类不规范写法的容错性更高,而Chrome的解析规则更严格,一旦文件名包含空格、特殊符号,Chrome会直接截断到特殊符号之前,若扩展名在截断内容之后,就会出现扩展名消失的问题。 - 你的代码存在两处逻辑瑕疵会放大该问题:
- 在执行
mysqli_fetch_assoc($result)获取$row变量之前,提前调用了$filepath = $row['code'],会抛出未定义变量的警告,可能污染响应内容 - 文件输出完成后还设置了
header("Refresh:0"),会产生多余的响应头,干扰浏览器解析
- 在执行
修复方案
1. 修正Content-Disposition头写法
将原代码中
header('Content-Disposition: attachment; filename=' . basename($row['code']));
替换为兼容全浏览器的写法:
$filename = basename($row['code']); $encoded_filename = rawurlencode($filename); // 同时设置filename和filename*参数,兼容所有主流浏览器解析规则 header('Content-Disposition: attachment; filename="'.$filename.'"; filename*=UTF-8\'\''.$encoded_filename);
2. 修正代码逻辑瑕疵
- 删除提前调用$row的无效代码:
$filepath = $row['code']; - 删除多余的刷新头:
header("Refresh:0"); - 在
readfile('images/' . $row['name']);后添加exit;,避免后续代码输出多余内容污染下载文件
3. 可选安全优化
你当前的SQL查询直接拼接$id参数,存在SQL注入风险,建议替换为预处理查询:
$stmt = $dbLink->prepare("SELECT * FROM file WHERE id=?"); $stmt->bind_param("i", $id); $stmt->execute(); $result = $stmt->get_result();
内容的提问来源于stack exchange,提问作者aidelakreyi
相关产品推荐
相关产品推荐

