最近接触Laravel框架ajax跨域请求的过程中遇到一些问题,在这里做下总结。
一开始发起ajax请求一直报500错误,搜索相关资料后发现Laravel要允许跨域请求可以加入Cors中间件,代码如下:
<?php namespace App\Http\Middleware; use Closure;
use Response;
class Cors { /**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{ $response = $next($request);
$response->header('Access-Control-Allow-Origin', '允许的域名');
$response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS,X-CSRF-TOKEN');
$response->header('Access-Control-Allow-Credentials', 'true');
return $response;
} }
之后发起ajax请求还是报500错误,发现POST请求需要验证CSRF令牌,于是根据官方文档所提示在ajax请求的头部及网页meta标签中加入该参数设置:
/*加入到网页头部中*/
<meta name="csrf-token" content="{{csrf_token()}}">
/*加到$.ajax请求之前*/
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
然而错误依旧,于是先到VerifyCsrfToken.php排除该请求,将要排除的 URL 添加到 $except 属性数组。之后便请求成功,然而问题还未结束,该请求过程中需要保存session参数然而却没有保存成功。由于session采用的是redis,所以沿着Session::save()方法往回查看哪里出问题了,使用Laravel的错误日志方法很方便,使用方法如下:
/*使用log*/
use Log;
/*在需要输出日志的地方使用以下方法*/
Log::info('错误提示信息');
根据错误提示追踪发现采用ajax发起的跨域请求所产生的seesion数据写入到新的ID当中,到此终于明白原来还是跨域导致无法识别当前用户的问题,最后在这篇文章中找到想要的答案:https://github.com/webplus/blog/issues/12,原来是发起ajax请求的时候并没有同时发送自身的cookie,加入方法如下:
$.ajax({
url : '请求链接',
//支持跨域发送cookies
xhrFields: {
withCredentials: true
},
crossDomain: true,
...
到此终于请求成功了,最后重新将该请求从VerifyCsrfToken.php的$except属性数组移除,重新发起带有CSRF令牌的ajax请求,大功告成。