You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP文件下载代码Safari正常Chrome丢失扩展名问题求助

问题产生原因

  1. 首先明确一个认知误区:PHP是服务端语言,所有代码均在服务器执行完成后才会将返回值传递给浏览器,不存在"PHP代码在浏览器运行表现不一致"的情况,你遇到的差异本质是不同浏览器对HTTP响应头的解析规则不同导致的。
  2. 核心问题出在Content-Disposition响应头的写法不规范:你设置filename参数时没有加双引号包裹,Safari对这类不规范写法的容错性更高,而Chrome的解析规则更严格,一旦文件名包含空格、特殊符号,Chrome会直接截断到特殊符号之前,若扩展名在截断内容之后,就会出现扩展名消失的问题。
  3. 你的代码存在两处逻辑瑕疵会放大该问题:
    • 在执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 11:18:04