Laravel页面用XMLHttpRequest调用API路由遇500错误及CSRF获取失败
核心错误分析
控制台报错Uncaught TypeError: Cannot read properties of null (reading 'getAttribute'),根源是页面中不存在<meta name="csrf-token">标签,导致document.querySelector返回null,无法调用getAttribute方法。这会直接中断请求发送流程,同时可能触发后续的500服务器错误。
解决步骤
1. 修复CSRF Token获取问题
根据你的API场景选择以下两种处理方式:
方式一:添加CSRF Meta标签
在Laravel视图模板(如全局布局文件resources/views/layouts/app.blade.php)的<head>区域添加CSRF标签,可直接使用Laravel内置指令:@csrf或手动编写:
<meta name="csrf-token" content="{{ csrf_token() }}">确保该标签加载在你的JS代码执行之前。
方式二:移除API请求的CSRF验证
Laravel默认对api中间件组的路由跳过CSRF验证(配置在app/Http/Middleware/VerifyCsrfToken.php的$except数组)。如果你的路由定义在routes/api.php中,直接删除JS里的CSRF请求头设置即可:// 删除此行代码 // xhr.setRequestHeader("X-CSRF-TOKEN", document.querySelector('meta[name="csrf-token"]').getAttribute("content"));
2. 排查500服务器错误
解决CSRF问题后若仍存在500错误,查看Laravel日志文件storage/logs/laravel.log,里面会有详细错误信息,常见场景及处理:
路由未正确定义
确保routes/api.php中存在对应POST路由:use App\Http\Controllers\CotacaoController; Route::post('/v1/cotacao', [CotacaoController::class, 'store']);控制器方法未正确处理请求
在控制器中确保能正确接收JSON格式的请求数据,并添加必要验证:public function store(Request $request) { // 验证请求字段规则 $validated = $request->validate([ 'products.*.description' => 'required|string', 'products.*.barcode' => 'required|string', 'products.*.price' => 'required|numeric', 'products.*.note' => 'nullable|string', ]); // 执行业务逻辑(如数据存储) // ... return response()->json(['message' => '数据提交成功'], 200); }请求数据格式不匹配
确认JS发送的JSON结构与后端预期一致,当前代码中JSON.stringify已处理格式,但需保证字段名与后端验证规则对应。
内容的提问来源于stack exchange,提问作者Ninguem

