Laravel中AJAX调用路由出现405方法不允许及404错误排查
问题分析与解决
核心问题
你遇到的两个错误根源是路由路径不匹配+Laravel POST请求缺少CSRF令牌验证:
- POST请求405:路由定义的是
/updateEventPrivacy,但AJAX请求的是/event/updateEventPrivacy,多了event/前缀导致找不到对应POST路由; - GET请求404:路由仅配置了POST方法,没有支持GET,自然匹配不到对应路由。
分步解决
1. 修正路由路径匹配
两种方案二选一:
方案A:修改AJAX请求URL,与路由定义一致
把app.js里的请求地址改成:
url: "/updateEventPrivacy",
方案B:修改路由,添加event前缀(更符合业务路径规范)
修改web.php的路由:
Route::post('event/updateEventPrivacy', 'EventController@updatePrivacy')->name('updateEventPrivacy');
推荐用命名路由生成URL避免硬编码出错:如果JS代码写在blade模板里,直接用blade语法生成地址:
url: "{{ route('updateEventPrivacy') }}",
如果app.js是独立静态文件,可在HTML中通过全局变量传递路由地址:
<script> window.updatePrivacyUrl = "{{ route('updateEventPrivacy') }}"; </script>
再在app.js中引用:
url: window.updatePrivacyUrl,
2. 处理Laravel CSRF令牌验证
Laravel默认拦截无CSRF令牌的POST请求,必须在AJAX中携带令牌:
第一步:在HTML头部添加CSRF meta标签(已存在则忽略)
<meta name="csrf-token" content="{{ csrf_token() }}">
第二步:在AJAX请求中加入令牌
可通过请求头传递,也可在请求参数里添加_token字段:
$.ajax({ method: "POST", url: "/updateEventPrivacy", // 或上述配置的正确地址 headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, data: { is_checked: is_checked , event_id: event_id }, success: function (response) { console.log(response); } })
3. (可选)支持GET请求(不推荐)
如果确实需要用GET修改状态,需在路由中添加GET方法支持:
// 同时支持POST和GET Route::match(['get', 'post'], 'updateEventPrivacy', 'EventController@updatePrivacy')->name('updateEventPrivacy'); // 或单独定义GET路由 Route::get('updateEventPrivacy', 'EventController@updatePrivacy');
注意:用GET请求修改数据不符合HTTP规范,建议优先使用POST。
修改后的完整示例(方案A)
web.php
Route::post('updateEventPrivacy', 'EventController@updatePrivacy')->name('updateEventPrivacy');
HTML
<meta name="csrf-token" content="{{ csrf_token() }}"> <div class="btn-container" id="smth-new"> <label class="switch btn-color-mode-switch"> <input type="checkbox" name="color_mode" id="color_mode" value="1" onchange="updatePrivacy('#color_mode', <?php echo $event->id ?>)"> <label for="color_mode" data-on="Private" data-off="Public" class="btn-color-mode-switch-inner"></label> </label> </div>
app.js
function updatePrivacy(ele, event_id) { var is_checked = $(ele).prop("checked"); console.log("Is checked: " + is_checked); console.log("Event id: " + event_id); $.ajax({ method: "POST", url: "/updateEventPrivacy", headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, data: { is_checked: is_checked , event_id: event_id }, success: function (response) { console.log(response); } }) }
内容的提问来源于stack exchange,提问作者Guilherme Moreira
相关产品推荐
相关产品推荐

