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

Laravel中使用Fetch API提交表单遇POST路由方法支持错误求助

Laravel使用Fetch API提交表单失败问题

我在Laravel中尝试通过Fetch API提交表单,但始终无法成功。原本不使用Fetch时表单能正常提交,但本次需求必须用Fetch实现。移除表单的action="{{ URL('/process') }}"属性仅依赖Fetch提交时,出现错误提示:The POST method is not supported for this route. Supported methods: GET, HEAD.

以下是我的相关代码:

表单代码

<form action="{{ url('/process')}}" method="POST">
       @csrf
       <div class="form-container">
         <div class="form-item">
           <label for="name">Full Name<span class="required">*</span></label>
           <input type="text" name="name" id="name" placeholder="Enter your name" />
         </div>   
         <div class="form-item">
            <label for="email">Email<span class="required">*</span></label>
            <input type="email" name="email" id="email" placeholder="Enter your email address" required />
         </div>
       </div>
       <div class="form-container">
          <button type="submit">Submit</button>
       </div>
</form>

Fetch API代码

form.addEventListener("submit", (e) => {
    e.preventDefault();
    const csrfToken = document.querySelector("input[name='_token']").value;
    fetch("success.blade.php", {
        method: "post",
        body: JSON.stringify(process),
        headers: {
            "Content-Type": "application/json",
            "X-CSRF-Token": csrfToken,
        },
    })
        .then((response) => {
            console.log(response);
            return response.text();
        })
        .then((text) => {
            return console.log(text);
        })
        .catch((error) => console.error(error));
}

路由配置

Route::get('/', [ContactController::class, 'create']);
Route::get('/all', [ContactController::class, 'getAll']);
Route::post('/process', [ContactController::class, 'store']);

ContactController.php代码

public function store(Request $request)
    {
    $contact = Contact::create($request->input());

    $message = 'Thank you for your message! We will review your submission and respond to you in 24-48 hours.';

    if ($request->ajax()) {
       return response()->json(compact('message'));
    }
    return view('success');
}

另外,我创建了success.blade.php用于显示提示信息,但不确定使用Fetch时是否还需要该文件。


问题分析与修复方案

1. Fetch请求地址错误

你当前Fetch请求的是success.blade.php,但Laravel的视图文件不能直接通过POST请求访问,必须通过路由定义的/process接口处理请求。把请求地址改为/process即可。

2. 请求体数据未正确收集

代码中的JSON.stringify(process)里的process是未定义变量,导致提交的数据为空。可以通过FormData快速收集表单数据,或者手动构建数据对象。

3. 请求头与后端接收方式不匹配

如果设置Content-Type: application/json,后端需要用$request->json()获取数据;如果用FormData,浏览器会自动设置正确的请求头,后端可以用$request->input()正常接收数据,更符合Laravel表单处理的习惯。

4. 可选:移除表单的action属性

虽然已经用e.preventDefault()阻止了默认提交行为,但移除action属性可以避免混淆,让代码更清晰。

关于success.blade.php

使用Fetch时,后端可以直接返回JSON格式的提示信息,前端通过JS在当前页面展示提示(比如弹窗、页面内提示框),无需跳转页面。如果需要跳转至成功页面,可以在Fetch请求成功后用window.location.href = '/success'实现,此时success.blade.php仍需保留,同时需要在路由中添加对应的GET路由:

Route::get('/success', function () {
    return view('success');
});

修复后的代码示例

修复后的Fetch代码

const form = document.querySelector('form');
form.addEventListener("submit", (e) => {
    e.preventDefault();
    const csrfToken = document.querySelector("input[name='_token']").value;
    // 用FormData收集表单数据
    const formData = new FormData(form);

    fetch("/process", {
        method: "POST",
        body: formData,
        headers: {
            "X-CSRF-Token": csrfToken,
            // 无需手动设置Content-Type,FormData会自动处理
        },
    })
    .then((response) => {
        if (!response.ok) {
            throw new Error('请求失败');
        }
        return response.json();
    })
    .then((data) => {
        console.log(data.message);
        // 页面内展示提示,比如创建一个提示元素
        const alertDiv = document.createElement('div');
        alertDiv.textContent = data.message;
        alertDiv.style.color = 'green';
        form.appendChild(alertDiv);
        // 如需跳转成功页面:
        // window.location.href = '/success';
    })
    .catch((error) => console.error(error));
});

调整后的控制器代码

public function store(Request $request)
{
    // 先验证表单数据,避免无效数据存入数据库
    $validated = $request->validate([
        'name' => 'required|string',
        'email' => 'required|email',
    ]);

    $contact = Contact::create($validated);

    $message = 'Thank you for your message! We will review your submission and respond to you in 24-48 hours.';

    // 针对Fetch请求直接返回JSON
    return response()->json(compact('message'));

    // 如果需要同时支持普通表单提交和Fetch请求,保留以下判断:
    // if ($request->wantsJson()) {
    //     return response()->json(compact('message'));
    // }
    // return view('success');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:50:34