Laravel PUT请求遇419未知状态码,Flutter端如何解决?
解决Flutter PUT请求Laravel出现419 CSRF错误的方案
先纠正VerifyCsrfToken的配置错误
你之前在VerifyCsrfToken.php里加的http://localhost/*是错误的,这个文件的$except数组匹配的是请求的路径部分,而非完整URL。正确操作:
打开app/Http/Middleware/VerifyCsrfToken.php,找到$except数组,添加你的更新路由路径:
protected $except = [ '/update/*', ];
检查Route::withoutMiddleware的使用是否正确
确保更新路由单独定义并正确跳过CSRF中间件,示例:
// 避免嵌套在Route::web()组内(若路由文件默认使用web组,单独提取该路由定义) Route::put('/update/{email}', [YourController::class, 'updateStatus'])->withoutMiddleware(['csrf']);
如果路由必须放在web组内,也可以保留上述写法,但要确认withoutMiddleware确实覆盖了组内默认的CSRF中间件。
若上述方法无效,直接在Flutter请求中携带CSRF令牌
Laravel默认会通过Cookie返回XSRF-TOKEN,可先获取该令牌再放入请求头:
第一步:在Laravel中添加获取CSRF令牌的路由
Route::get('/csrf-cookie', function () { return response()->json(['status' => 'ok']); });
第二步:修改Flutter代码,先获取令牌再发起请求
Future<void> updateState(String email, String newValue) async { // 先获取CSRF令牌 final csrfResponse = await http.get(Uri.parse('http://localhost/csrf-cookie')); String? xsrfToken; if (csrfResponse.headers['set-cookie'] != null) { // 从Cookie中解析XSRF-TOKEN final cookies = csrfResponse.headers['set-cookie']!.split(';'); for (var cookie in cookies) { if (cookie.trim().startsWith('XSRF-TOKEN=')) { xsrfToken = cookie.trim().substring('XSRF-TOKEN='.length); xsrfToken = Uri.decodeComponent(xsrfToken); // 解码URL编码的令牌 break; } } } final apiUrl = 'http://localhost/update/$email'; final headers = { 'Content-Type': 'application/json', if (xsrfToken != null) 'X-XSRF-TOKEN': xsrfToken, }; final requestData = {'is_active': newValue}; try { final response = await http.put( Uri.parse(apiUrl), headers: headers, body: jsonEncode(requestData), ); if (response.statusCode == 200) { print('Record updated successfully'); } else { print('Failed to update record: ${response.body}'); } } catch (e) { print('Error: $e'); } }
额外注意事项
- 若使用安卓模拟器,Flutter中的
localhost需替换为10.0.2.2(模拟器的localhost指向自身,而非电脑上的Laravel服务);iOS模拟器可直接使用localhost。 - 可查看Laravel日志文件
storage/logs/laravel.log,里面会有419错误的具体细节,帮助快速定位问题。
内容的提问来源于stack exchange,提问作者phenomenal
相关产品推荐
相关产品推荐

