最近接觸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請求,大功告成。