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

Symfony框架下通过AJAX从控制器导出JSON文件无响应问题求助

问题原因及修复方案

核心问题梳理

  • AJAX 本身不会自动触发浏览器的下载弹窗,请求返回的内容只会存储在 JS 内存中,你代码中done回调为空没有做后续处理,自然看不到任何响应
  • 控制器没有按照 Symfony 规范使用 Response 对象,手动输出 header、往php://output写内容后返回空 Response,之前的输出会被 Symfony 的缓冲机制丢弃
  • 控制器代码中没有对$mydata赋值,也没有取出前端传递的data参数
  • 缺少 CSRF 令牌校验/传递,Symfony 默认拦截没有合法 CSRF 令牌的 POST 请求,也会导致无响应

修复方案

方案一:改用表单提交触发下载(兼容性最佳,代码更简单)

不需要用 AJAX,动态创建表单提交即可触发浏览器默认下载行为:

const form = document.createElement('form');
form.method = 'POST';
form.action = '{{ path('export_index', {'type': 'json'}) }}';
// 传入CSRF令牌
const csrfInput = document.createElement('input');
csrfInput.name = '_token';
csrfInput.value = '{{ csrf_token('export') }}';
form.appendChild(csrfInput);
// 传入你的业务数据
const dataInput = document.createElement('input');
dataInput.name = 'data';
dataInput.value = JSON.stringify(data);
form.appendChild(dataInput);
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);

方案二:保留AJAX的修复方式

修改AJAX代码,在回调中手动触发下载:

$.ajax({
    url: '{{ path('export_index', {'type': 'json'}) }}',
    type: 'POST',
    data: {
        data: data,
        _token: '{{ csrf_token('export') }}'
    },
    xhrFields: {
        responseType: 'blob' // 指定返回类型为二进制流
    }
}).done(function(blob) {
    // 动态生成下载链接触发下载
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'data.json';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    document.body.removeChild(a);
});

控制器代码修复

完全遵循 Symfony 规范使用 Response 对象处理输出:

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;

public function export(Request $request, CsrfTokenManagerInterface $csrfTokenManager): Response {
    // 校验CSRF令牌
    $csrfToken = new CsrfToken('export', $request->request->get('_token'));
    if (!$csrfTokenManager->isTokenValid($csrfToken)) {
        throw $this->createAccessDeniedException('非法请求');
    }
    // 取出前端传递的data参数
    $rawData = $request->request->get('data');
    $mydata = is_string($rawData) ? $rawData : json_encode($rawData);
    
    // 统一通过Response设置响应头和返回内容
    $response = new Response($mydata);
    $response->headers->set('Content-Type', 'application/json');
    $response->headers->set('Content-Disposition', 'attachment; filename="data.json"');
    $response->headers->set('Expires', '0');
    $response->headers->set('Cache-Control', 'must-revalidate');
    $response->headers->set('Content-Length', strlen($mydata));
    
    return $response;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:57:01