最近在使用 laravel 開發(fā)時碰到了需要在跨域ajax請求中攜帶cookie的需求,參考
Laravel開啟跨域請求 和 跨域Ajax請求時是否帶Cookie的設置 ;
laravel
執(zhí)行命令:php artisan make:middleware Cors
讶踪,在/app/Http/Middleware/ 目錄下會出現(xiàn)一個Cors.php 文件,在其handle 方法中加入如下內容:
// Cors.php
$response = $next($request);
$response->header('Access-Control-Allow-Origin', '*');
$response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept, multipart/form-data, application/json');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
$response->header('Access-Control-Allow-Credentials', 'false');
return $response;
完整Cors文件:
<?php
namespace App\Http\Middleware;
use Closure;
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);
$origin = $request->server('HTTP_ORIGIN') ?: '';
$allow_origin = [
'http://localhost:3000',
'https://www.xxx.com',
];
if (in_array($origin, $allow_origin)) {
$response->header('Access-Control-Allow-Origin', $origin);
$response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept, Authorization');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS, DELETE');
$response->header('Access-Control-Allow-Credentials', 'true');
}
return $response;
}
}
其中有以下需要注意的地方:
- 對于跨域訪問并需要伴隨認證信息的請求,需要在 XMLHttpRequest 實例中指定 withCredentials 為 true
(具體見下方jQuery ajax部分)
。- 這個中間件你可以根據(jù)自己的需求進行構建扔役,如果需要在請求中伴隨認證信息(包含 cookie,session)那么你就需要指定
Access-Control-Allow-Credentials
為true
, 因為對于預請求來說如果你未指定該響應頭警医,那么瀏覽器會直接忽略該響應厅目。- 在響應中指定
Access-Control-Allow-Credentials
為true
時,Access-Control-Allow-Origin
不能指定為 *(這個一定要注意法严,我就是在這個地方調了好久)- 后置中間件只有在正常響應時才會被追加響應頭,而如果出現(xiàn)異常葫笼,這時響應是不會經過中間件的深啤。
// jQuery ajax
$.ajax({
url : 'http://remote.domain.com/corsrequest',
data : data,
dataType: 'json',
type : 'POST',
xhrFields: {
withCredentials: true // 發(fā)送Ajax時,Request header中會帶上 Cookie 信息路星。
},
crossDomain: true, // 發(fā)送Ajax時溯街,Request header 中會包含跨域的額外信息,但不會含cookie
contentType: "application/json",
...