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

Laravel 9 AJAX加载模态框表单报Undefined variable $errors错误

Laravel 9 加载模态框报Undefined variable $errors错误修复

问题相关代码

触发模态框的页面代码

<div>
<x-button onclick="viewFormAdd()" data-bs-toggle="modal" type="button">Add New Data</x-button>
</div>

<script>
function viewFormAdd() {
        $.get("{{ route('kategori.create') }}", {},
            function(data, status) {
                $('.viewmodal').html(data).show();
                $('#modalCreateKategori').modal('show');
            }
        );
    }
</script>

模态框视图createKategori.blade.php代码

<x-modal modalId="modalCreateKategori" modalTitle="Tambah Kategori">
<form method="post" action="{{ route('kategori.store') }}" class="formtambah">
    @csrf
    <div class="grid grid-rows-2">
        <div>
            <x-label>Nama Kategori</x-label>
            <x-input type="text" name="nama_kategori" id="nama_kategori" />
            @error('nama_kategori')
                <small>{{ $message }}</small>
            @enderror
        </div>
        <div class="justify-end items-center">
            <x-button type="submit">Simpan</x-button>
        </div>
    </div>
</form></x-modal>

表单AJAX提交代码

<script>
$(document).ready(function() {
    $('.formtambah').submit(function(e) {
        e.preventDefault();
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
        $.ajax({
            type: "post",
            url: $(this).attr('action'),
            data: $(this).serialize(),
            dataType: "json",
            success: function(response) {
                if (response.tersimpan) {
                    Swal.fire({
                        position: 'center',
                        icon: 'success',
                        title: 'Tersimpan!',
                        text: response.tersimpan,
                        showConfirmButton: false,
                        timer: 1500
                    })
                    $('.btn-close').click();
                    dataKategori();
                }
            },
            error: function(xhr, thrownError) {
                alert(xhr.status + "\n" + xhr.responseText + "\n" + thrownError);
            }
        });
        return false;
    });
});</script>

控制器代码

public function create()
{
   return view('kategori.createKategori');
}

public function store(KategoriRequest $request)
{
   $kategori = new Kategoris;
    $kategori->namakat = $request->nama_kategori;
    $kategori->save();

    $msg = [
        'tersimpan'=> 'Produk baru berhasil tersimpan!'
    ];

    return response()->json($msg);
}

表单验证类代码

class KategoriRequest extends FormRequest{

public function authorize()
{
    return true;
}

public function rules()
{
    return [
        'nama_kategori' => 'required'
    ];
}

public function messages()
{
    return[
        'nama_kategori.required' => 'Maaf, nama kategori harus diisi'
    ];
}
}

问题现象

点击按钮加载模态框时接口返回500错误,报错信息:

Undefined variable $errors (View: C:\xampp\htdocs\newsinartimur_laravel_9\resources\views\kategori\createKategori.blade.php)

浏览器抓包显示请求地址为http://localhost:8000/api/kategori/create,返回500状态码。删除视图中@error相关的验证提示代码后,模态框和表单可正常运行。

故障原因

你的kategori.create路由被定义在api.php路由文件中,默认走API路由组。Laravel的API路由组默认不会加载StartSession、ShareErrorsFromSession这两个Web中间件,而Blade的@error指令依赖ShareErrorsFromSession中间件向视图注入的$errors变量,API路由下没有这个变量,就会触发未定义变量错误。

修复方案

选择任意一种方案即可:

  • 方案1(推荐):将kategori相关的资源路由从api.php迁移到web.php路由文件。这类需要返回视图、依赖session、表单验证错误提示的交互逻辑属于Web场景,走Web中间件栈后会自动加载session相关逻辑,$errors变量会自动注入视图,@error指令可正常工作。
  • 方案2:如果必须将该路由放在API路由下,手动给对应路由/路由组补充缺失的中间件。打开app/Http/Kernel.php,在api中间件组中添加如下两个中间件:
protected $middlewareGroups = [
    'api' => [
        // 原有API中间件保持不动
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    ],
];

注意:API路由默认设计为无状态,添加session相关中间件会破坏API的无状态特性,非必要不选这个方案。

  • 方案3(临时兼容):在视图中先判断$errors变量是否存在再输出错误,仅用于临时规避问题,不推荐长期使用:
@if(isset($errors) && $errors->has('nama_kategori'))
    <small>{{ $errors->first('nama_kategori') }}</small>
@endif

额外提示:当前控制器中存储成功的提示文案为Produk baru berhasil tersimpan!(新产品保存成功),和当前分类(kategori)存储逻辑不匹配,建议修改为对应分类的提示文案避免误导。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:01:09