WordPress插件生成CSV无法下载:如何捕获重定向实现下载?
WordPress CSV下载插件问题排查
我正在开发一款WordPress插件,用于生成CSV文件并允许管理员下载。已有可正常生成CSV数据的generate_csv()函数(返回CSV内容字符串),但无法实现下载功能。尝试相关方案后仍无法捕获重定向。
当前使用的表单代码
<form method="GET" action="data.csv"> <input type="submit" class="button button-primary" value="Download CSV"></input> </form>
当前捕获重定向的代码
function download_redirect() { if ($_SERVER['REQUEST_URI']=='/wp-admin/data.csv?') { $csv_data = generate_csv(); header('Content-Disposition: attachment; filename="data.csv"'); header('Content-Type: text/csv'); header('Content-Length: ' . strlen($csv_data)); header('Connection: close'); echo $csv_data; exit(); } } add_action('template_redirect','download_redirect');
问题分析与修正方案
你主要遗漏了以下几个关键要点:
严格的REQUEST_URI匹配不可靠
直接判断$_SERVER['REQUEST_URI'] == '/wp-admin/data.csv?'过于死板,实际请求的URI可能没有末尾的?,或者包含额外参数,导致无法触发逻辑。WordPress的路由系统也不会默认识别data.csv这种伪静态路径,应该改用WordPress原生的动作钩子机制。表单Action设置错误
表单指向data.csv会让请求进入WordPress的404处理流程,无法被你的钩子捕获。正确的做法是利用WordPress后台的admin.php入口,通过自定义action参数来触发下载逻辑。Header输出前存在潜在输出
template_redirect钩子虽早,但可能已有其他插件/主题输出了空格或字符,导致Header无法发送。需要清空输出缓冲区,确保Header能正常生效。文件名转义错误
Header中文件名使用"是HTML转义字符,PHP输出时应该直接使用原生双引号。
修正后的代码示例
修改后的表单代码
<form method="GET" action="<?php echo admin_url('admin.php'); ?>"> <input type="hidden" name="action" value="download_csv"> <input type="submit" class="button button-primary" value="Download CSV"> </form>
修改后的下载处理代码
// 注册后台动作钩子,处理CSV下载请求 add_action('admin_action_download_csv', 'handle_admin_csv_download'); function handle_admin_csv_download() { // 验证用户权限,仅管理员可下载 if (!current_user_can('manage_options')) { wp_die('无权限执行此操作'); } // 生成CSV数据 $csv_data = generate_csv(); // 清空输出缓冲区,避免之前的输出干扰Header ob_clean(); flush(); // 设置下载相关Header header('Content-Disposition: attachment; filename="data.csv"'); header('Content-Type: text/csv; charset=utf-8'); header('Content-Length: ' . strlen($csv_data)); header('Cache-Control: no-store, no-cache, must-revalidate'); // 输出CSV内容并终止程序 echo $csv_data; exit; }
关键改进说明
- 使用
admin_action_前缀钩子:WordPress会自动识别admin.php?action=download_csv这样的请求,直接触发对应处理函数,比判断URI更稳定。 - 权限校验:确保只有具备管理员权限的用户才能触发下载,提升安全性。
- 输出缓冲区处理:
ob_clean()和flush()清空所有之前的输出,保证Header能正常发送。 - 规范Header设置:明确字符编码和缓存控制,避免浏览器解析异常。
内容的提问来源于stack exchange,提问作者Ythaenagor
相关产品推荐
相关产品推荐

