跨域ajax携带cookie
2018-05-25 本文已影响0人
forever_youyou
最近在使用 laravel 开发时碰到了需要在跨域ajax请求中携带cookie的需求,参考
Laravel开启跨域请求 和 跨域Ajax请求时是否带Cookie的设置 ;
laravel
执行命令:php artisan make:middleware Cors
,在/app/Http/Middleware/ 目录下会出现一个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部分)
。- 这个中间件你可以根据自己的需求进行构建,如果需要在请求中伴随认证信息(包含 cookie,session)那么你就需要指定
Access-Control-Allow-Credentials
为true
, 因为对于预请求来说如果你未指定该响应头,那么浏览器会直接忽略该响应。- 在响应中指定
Access-Control-Allow-Credentials
为true
时,Access-Control-Allow-Origin
不能指定为 *(这个一定要注意,我就是在这个地方调了好久)- 后置中间件只有在正常响应时才会被追加响应头,而如果出现异常,这时响应是不会经过中间件的。
// jQuery ajax
$.ajax({
url : 'http://remote.domain.com/corsrequest',
data : data,
dataType: 'json',
type : 'POST',
xhrFields: {
withCredentials: true // 发送Ajax时,Request header中会带上 Cookie 信息。
},
crossDomain: true, // 发送Ajax时,Request header 中会包含跨域的额外信息,但不会含cookie
contentType: "application/json",
...