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

Laravel Ajax返回HTML中@csrf未渲染、Token失效问题求助

我来帮你解决这个问题,咱们一步步来分析和修复:

问题根源分析

你遇到的两个核心问题:

  1. @csrf直接显示未渲染:因为@csrf是Laravel Blade模板引擎的专属指令,你直接在控制器里把它拼进字符串echo输出,Laravel不会解析这个指令,所以会原样输出文本。
  2. Token无法正常工作:一方面是上面的@csrf没生成有效token,另一方面你循环生成的表单/按钮都用了相同的ID(比如view_attachie、btnViewDoc),这会导致JS选择器混乱,事件绑定失效;另外内联的onclick="frmViewDOC()"对于动态生成的元素也可能存在绑定问题。
解决方案

我推荐两种修复方式,优先用第一种(更符合Laravel最佳实践):

方式一:改用Blade视图渲染HTML(推荐)

把拼接HTML的逻辑从控制器移到Blade视图文件里,让Laravel帮你解析Blade指令,同时代码更易维护。

步骤1:创建Blade视图文件

比如在resources/views/attachments/list.blade.php里写HTML结构:

<table border="2">
    @foreach($attachments as $row)
        <tr>
            <td>
                <form name="view_attachie_{{$row->id}}" class="row view-attach-form" action="{{ route('viewDOC') }}" method="post">
                    @csrf
                    <input type="hidden" name="myfile[]" value="{{ $row->your_file_column }}"> {{-- 替换成你表中存储文件的实际字段名 --}}
                    <td>{{ $row->description }}</td>
                    <td>
                        <button type="submit" class="btn btn-sm btn-primary view-doc-btn">View The Attachment</button>
                    </td>
                </form>
            </td>
        </tr>
    @endforeach
</table>

注意:

  • 用route('viewDOC')生成正确的路由URL(前提是你在routes/web.php里给viewDOC方法定义了路由名称)
  • 给每个表单加唯一的name(比如view_attachie_{{$row->id}}),避免ID重复的问题
  • 把myfile[]的value设置为实际的文件标识(比如文件名/存储路径,根据你的表结构来)

步骤2:修改控制器代码

控制器不再拼接HTML,而是传递数据到视图,渲染后返回:

public function fetchFiles(Request $request) { 
    $application_id = $request->get('application_id'); 
    $applicant_id = $request->get('applicant_id'); 
    $attachments = DB::table('applicant_attachments')
        ->where('applicant_id', $applicant_id)
        ->where('application_id', $application_id)
        ->get(); 
    
    // 返回渲染后的视图HTML
    return view('attachments.list', compact('attachments'))->render();
}

步骤3:优化JS事件绑定(可选)

如果原来的frmViewDOC()有自定义逻辑,不要用内联onclick,改用事件委托(比如绑定到页面的父容器):

// 假设你的表格放在id为attachments-container的元素里
document.getElementById('attachments-container').addEventListener('click', function(e) {
    if (e.target.classList.contains('view-doc-btn')) {
        e.preventDefault(); // 如果需要自定义提交逻辑
        const form = e.target.closest('.view-attach-form');
        // 这里写你的frmViewDOC逻辑,比如提交表单或者做其他操作
        form.submit(); // 或者自定义AJAX提交
    }
});

方式二:控制器手动生成CSRF Token(快速修复)

如果不想改视图,直接在控制器里手动拼接CSRF的隐藏输入框:

修改控制器的HTML拼接部分

public function fetchFiles(Request $request) { 
    $application_id = $request->get('application_id'); 
    $applicant_id = $request->get('applicant_id'); 
    $data = DB::table('applicant_attachments')
        ->where('applicant_id', $applicant_id)
        ->where('application_id', $application_id)
        ->get(); 
    
    $output = '<table border="2">'; 
    $myAction = route('viewDOC'); // 用route生成正确URL,避免硬编码
    $csrfToken = csrf_token(); // 获取当前CSRF Token
    
    foreach($data as $row) { 
        // 每个表单用唯一的ID/name,避免重复
        $formId = 'view_attachie_' . $row->id;
        $output .= '<tr><td><form name="'.$formId.'" id="'.$formId.'" class="row view-attach-form" action="'.$myAction .'" method="post">';
        // 手动添加CSRF Token输入框
        $output .= '<input type="hidden" name="_token" value="'.$csrfToken.'">';
        $output .= '<td><input type="hidden" name="myfile[]" id="myfile_'.$row->id.'" value="'.$row->your_file_column.'">'.$row->description .' </td>';
        $output .= '<td><button class="btn btn-sm btn-primary view-doc-btn" onclick="frmViewDOC(\''.$formId.'\');">View The Attachment</button></td>';
        $output .= '</form></td></tr>'; 
    } 
    $output .='</table>'; 
    echo $output; 
}

然后修改frmViewDOC函数,接收表单ID参数,避免选择错误的表单:

function frmViewDOC(formId) {
    const form = document.getElementById(formId);
    // 执行你的逻辑,比如提交表单
    form.submit();
}
额外注意事项
  • 确保viewDOC路由已经正确定义,并且接收POST请求
  • 动态生成的元素尽量用类选择器,避免ID重复导致的JS问题
  • 优先使用Blade视图渲染HTML,这是Laravel的设计初衷,代码更易维护和扩展

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:51:29