Laravel 5.7 Ajax 发布请求返回 419 状态码
Posted
技术标签:
【中文标题】Laravel 5.7 Ajax 发布请求返回 419 状态码【英文标题】:Laravel 5.7 Ajax post request returns 419 status code 【发布时间】:2019-05-18 10:44:28 【问题描述】:您好,我是 Laravel 的新手,我正在尝试使用 ajax 表单提交构建一个登录表单。
我使用 Metronic 模板复制并构建了一个示例表单,并尝试使用 ajax 请求来获取登录检查。
如果我将其从 VerifyCsrfToken 检查中排除,我的代码完全可以正常工作。但我确实希望令牌验证能够正常工作。
我已经阅读了多篇关于 csrf 令牌的帖子,尝试过但仍然返回状态码 419。
对不起,下面的代码很长,但在这里 (我知道我没有做任何设置会话和东西的事情,请暂时忽略,因为代码无论如何都会返回 419 状态)
路由/web.php
Route::post('/auth/login', array('uses' => 'Auth\LoginController@postLogin'))->name('login');
Route::get('/landing', array('uses' => 'IndexController@landing'))->name('landing');
login.blade.php
<head>
<meta charset="utf-8" />
<title> config('app.name') ( config('app.env') )</title>
<meta name="description" content="Latest updates and statistic charts">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
<meta name="csrf-token" content=" csrf_token() ">
<!--
Global css & js here
-->
</head>
<body>
<form class="m-login__form m-form" method="post" action=" route('login') ">
@csrf
<!--
Form content here
-->
</form>
<!--begin::Page Scripts -->
<script type="text/javascript">
var form_action = ' route('login') ';
</script>
<script src=" URL::asset('login.js')" type="text/javascript"></script>
<!--end::Page Scripts -->
</body>
login.js
var handleSignInFormSubmit = function()
$('#m_login_signin_submit').click(function(e)
e.preventDefault();
var btn = $(this);
var form = $(this).closest('form');
form.validate(
rules:
email:
required: true,
email: true
,
password:
required: true
);
if (!form.valid())
return;
btn.addClass('m-loader m-loader--right m-loader--light').attr('disabled', true);
var formData = form.serialize();
$.ajax(
url:form_action,
type:'POST',
data: formData,
headers:
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
,
dataType: 'json',
success:function(data)
if(data.auth)
$(location).attr('href', data.intended);
else
btn.removeClass('m-loader m-loader--right m-loader--light').attr('disabled', false);
showErrorMsg(form, 'danger', 'Incorrect username or password. Please try again.');
,
error: function (data)
btn.removeClass('m-loader m-loader--right m-loader--light').attr('disabled', false);
showErrorMsg(form, 'danger', 'Incorrect username or password. Please try again.');
);
);
身份验证\登录控制器
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\URL;
use Response;
class LoginController extends Controller
use AuthenticatesUsers;
protected $redirectTo = '/landing';
public function __construct()
$this->middleware('guest')->except('logout');
public function postLogin(Request $request)
$auth = false;
$credentials = $request->only('email', 'password', 'remember_token');
if (Auth::attempt($credentials, $request->has('remember_token')))
$auth = true; // Success
if($auth)
if ($request->ajax())
$response = array(
'auth' => true,
'code' => 101,
'intended' => URL::route('landing')
);
else
$response = array(
'auth' => true,
'code' => 102,
'intended' => URL::route('landing')
);
return Response::json($response);
else
$response = array(
'status' => 'error',
'msg' => 'Error',
);
return Response::json($response);
部分响应错误
message: "", exception: "Symfony\Component\HttpKernel\Exception\HttpException",…
exception: "Symfony\Component\HttpKernel\Exception\HttpException"
file: "/var/www/imas/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php"
line: 204
message: ""
更新: 我把所有东西都放在一个 php 文件中,确实将 csrf-token 元数据放在 head + ajaxsetup 中,仍然得到 419 状态码 (注:“test123”是路由文件中的post方法)
<!DOCTYPE html>
<html lang="en">
<!-- begin::Head -->
<head>
<meta charset="utf-8" />
<title> config('app.name') ( config('app.env') )</title>
<meta name="description" content="Latest updates and statistic charts">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
<meta name="csrf-token" content=" csrf_token() ">
<!--begin::Web font -->
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js"></script>
<script>
WebFont.load(
google: "families":["Poppins:300,400,500,600,700","Roboto:300,400,500,600,700"],
active: function()
sessionStorage.fonts = true;
);
</script>
<!--end::Web font -->
<!--begin:: Global Mandatory Vendors -->
<!--end:: Global Mandatory Vendors -->
<!--begin:: Global Optional Vendors -->
<!--end:: Global Optional Vendors -->
<!--begin::Global Theme Styles -->
<!--end::Global Theme Styles -->
<!--begin::Page Vendors Styles -->
<!--end::Page Vendors Styles -->
<!--begin:: Custom CSS -->
@yield('pagespecificstyles')
<!--end:: Custom CSS -->
</head>
<!-- end::Head -->
<!-- begin::Body -->
<body class="m-page--fluid m--skin- m-content--skin-light2 m-header--fixed m-header--fixed-mobile m-aside-left--enabled m-aside-left--skin-light m-aside-left--fixed m-aside-left--offcanvas m-footer--push m-aside--offcanvas-default">
<!-- begin:: Page -->
<div class="m-grid m-grid--hor m-grid--root m-page">
<!-- BEGIN: Header -->
@include('admin.top')
<!-- END: Header -->
<!-- begin::Body -->
<div class="m-grid__item m-grid__item--fluid m-grid m-grid--ver-desktop m-grid--desktop m-body">
<!-- BEGIN: Left Aside -->
@include('admin.sidenav')
<!-- END: Left Aside -->
<div class="m-grid__item m-grid__item--fluid m-wrapper">
<form name="form1" id="form1">
Name: <input type="name" name="username" id="username"/><br/>
Password: <input type="password" name="password" id="password"/><br/>
<input type="button" value="Submit" name="btn_submit" id="btn_submit"/>
</form>
</div>
</div>
<!-- end:: Body -->
<!-- begin::Footer -->
@include('admin.footer')
<!-- end::Footer -->
</div>
<!-- end:: Page -->
<!-- begin::Scroll Top -->
@include('admin.scrolltop')
<!-- end::Scroll Top -->
<!-- begin:: Script -->
@include('admin.script')
@yield('pagespecificscripts')
<script>
var formPath = ' route('test123') ';
$(document).ready(function()
$.ajaxSetup(
headers:
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
);
$('#btn_submit').click(function()
var formData = $('#form1').serialize();
$.ajax(
type:'POST',
url:formPath,
data:formData,
success:function(data)
alert(data);
);
);
);
</script>
<!-- end:: Script -->
</body>
<!-- end::Body -->
</html>
【问题讨论】:
你的路由有web
中间件吗?
在“->name('xxxx')”之后添加了“->middleware('web')”,没有运气
嗯不确定它是否会影响,但请尝试删除 csrf 令牌之一,您正在传递 2,一个来自 <form>
,一个来自 ajax 的 headers
***.com/questions/46266553/…
【参考方案1】:
在 HTML 的头部使用这个:
<head>
<meta name="csrf-token" content=" csrf_token() " />
</head>
并且在你的 ajax 中使用它的数据:
<script>
$.ajaxSetup( headers: 'X-CSRF-TOKEN': jQuery('meta[name="csrf-token"]').attr('content') );
</script>
请参考 Laravel 文档CSRF Protection
【讨论】:
meta 标签已经在 login.blade 的头部 问题可能是 jquer/js 脚本被分隔在另一个 .js 文件中吗? (因为我确实在 .js 文件中尝试了 $.ajaxSetup 并没有帮助)以上是关于Laravel 5.7 Ajax 发布请求返回 419 状态码的主要内容,如果未能解决你的问题,请参考以下文章
e.preventDefault 不适用于 laravel 5.7