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

Azure Linux Web App部署的PHP8站点生成CSV直接展示而非下载问题

问题原因排查及修复方案
    1. 重复设置Content-Type响应头导致优先级冲突,属于不规范写法
    1. Content-Length取值错误:你声明的响应长度是本地文件geodata.csv的大小,但代码全程没有向这个本地文件写入任何内容,反而把CSV内容直接写到了php://output输出流,导致实际响应长度和声明长度不匹配,浏览器无法正确识别为下载附件
    1. 变量名笔误:行fputcsv($output, array('name','loc','zip'), chr(6));中的$output变量未定义,你实际创建的句柄是$file,这会触发PHP警告,警告内容会提前输出到响应,导致后续设置的下载相关header失效
    1. 输出缓冲清理时机错误:ob_end_clean()应该在发送任何header之前执行,避免之前有输出内容导致header被提前发送失效
    1. 冗余逻辑:已经把CSV内容写到php://output输出流,最后又调用readfile("geodata.csv")属于多余操作,还会输出不存在的文件内容或触发报错
修复后的代码
<?php
// 先清空所有层级的输出缓冲,避免之前的输出导致header失效
while (ob_get_level()) ob_end_clean();

// 统一设置响应头,不要重复定义Content-Type
header('Content-Description: File Transfer');
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=geodata.csv");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');

// 直接输出到php://output,无需创建本地临时文件
$file = fopen('php://output', 'w') or die ("Unable to create file in write mode");

// 修复变量名错误,使用已定义的$file句柄
fputcsv($file, array('name','loc','zip'), chr(6));
$mrows = mysqli_query($myconnection, "SELECT name,loc,zip FROM geo_tbl WHERE sp = 'FL'");
while ($mrow = mysqli_fetch_assoc($mrows)) {
    fputcsv($file, $mrow, chr(6));
}
fclose($file);

// 内容已全部输出,无需额外调用readfile
exit();
Azure Linux Web App额外检查项
  • 确认PHP代码开头没有任何空格、HTML内容、UTF-8 BOM头输出,这类隐形输出会导致header提前发送失效
  • 确认Azure Web App的PHP配置没有开启output_handler强制改写输出,也没有Nginx反向代理规则修改Content-Disposition响应头
  • 如果仍有问题,可以在设置自定义header前加一行header_remove('Content-Type')先清空服务端默认设置的Content-Type,避免被覆盖

内容的提问来源于stack exchange,提问作者Redzon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:45:05