Laravel 9 中使用Ajax更新数据库记录返回404错误求助
嘿,我来帮你排查下这个404的问题~
首先最核心的问题出在你的Ajax请求URL上!你现在写的是 '/change_item_price/{id}/{our_cost}',这里的{id}和{our_cost}是Laravel路由定义里的占位符,但你在JS里直接这么写的话,浏览器会把它当成字面量路径去发送请求,也就是说实际请求的地址是/change_item_price/{id}/{our_cost},这完全匹配不上你定义的带真实参数的路由,所以直接返回404了。
第一步:修正Ajax的URL
你需要把JS里的实际变量item_id和new_price替换到URL里,用ES6的模板字符串最方便:
data = { _token: "{{csrf_token()}}", // 这里只需要带CSRF token就行,参数已经在URL里了 }; $.ajax({ url: `/change_item_price/${item_id}/${new_price}`, data: data, type: 'POST', success: function( data ) { console.log(data); } });
要是你习惯用Laravel的路由生成,可以在页面里提前生成好URL,比如直接在JS里用{{ route('change_item_price', ['id' => item_id, 'our_cost' => new_price]) }},不过要注意如果是外部JS文件,blade语法不生效,这时候就用变量拼接的方式就好。
第二步:修正控制器里的小bug
你的控制器代码里有个细节错误:你已经用$get_id = Item::findOrFail($id);拿到了模型实例,但后面where('id', $get_id)这里传的是模型对象,不是id值,数据库会把它当成字符串去匹配,肯定不对。其实完全可以用更符合Laravel Eloquent风格的写法简化:
public function change_item_price($id, $our_cost){ // 直接用findOrFail获取模型,不存在会自动返回404,符合需求 $item = Item::findOrFail($id); // 用Eloquent更新字段 $item->our_cost = $our_cost; $item->save(); // 直接返回更新后的模型 return $item; }
要是你坚持用DB门面的话,应该改成这样:
public function change_item_price($id, $our_cost){ Item::findOrFail($id); // 先验证id存在 DB::table('items') ->where('id', $id) ->update([ 'our_cost' => $our_cost ]); return Item::where('id',$id)->first(); }
额外小建议
其实POST请求更推荐把参数放在请求体里,而不是URL上,这样路由可以改成:
Route::post('/change_item_price',[itemController::class, 'change_item_price'])->name('change_item_price');
控制器改成从请求里取参数:
public function change_item_price(Request $request){ // 先验证参数合法性 $request->validate([ 'id' => 'required|exists:items,id', 'our_cost' => 'required|numeric', ]); $item = Item::findOrFail($request->id); $item->our_cost = $request->our_cost; $item->save(); return $item; }
对应的Ajax代码改成:
data = { id: item_id, our_cost: new_price, _token: "{{csrf_token()}}", }; $.ajax({ url: '/change_item_price', data: data, type: 'POST', success: function( data ) { console.log(data); } });
这种方式更符合RESTful规范,参数也不会暴露在URL里,安全性更好。
备注:内容来源于stack exchange,提问作者T.A.

