前后端分离跨域问题
自己动手丰衣足食最近写一个投票系统前端mui在与后端交互过程中遇到一个错误。
一看原来是跨域问题
先说本地开发解决方案
示例是mui找到mainfest.json文件在h5下面有个devServer添加如下
"proxy": {
"/api": {
"target": "https://xxx.zhizubaba.com/api",
"changeOrigin": true,
"secure": false,
"pathRewrite": {
"^/api": ""
}
}
}
加这个的意思是遇到/api用https://xxx.zhizubaba.com/api替换代理需要注意的是请求接口的时候要 /api/xxx 这样写请求接口的地址这样就可以解决在本地开发中的跨域问题
线上环境环境 PHP+Nginx+mui
后台处理php框架laravel
//创建中间件
php artisan make:middleware EnableCrossRequestMiddleware
//中间件代码
public function handle($request, Closure $next)
{
$response = $next($request);
//获取请求域名
$origin = $request->server('HTTP_ORIGIN') ? $request->server('HTTP_ORIGIN') : '';
$allow_origin = config('whitelist.cross');
//判断请求域名是否在跨域白名单
if (in_array($origin, $allow_origin)) {
$response->header('Access-Control-Allow-Origin', $origin);
$response->header('Access-Control-Allow-Headers', 'Content-Length,Content-Type,Authorization, Accept,X-Requested-With,X-Requested-Token,x-requested-token');
$response->header('Access-Control-Expose-Headers', 'Authorization, authenticated');
$response->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE, PATCH, HEAD');
$response->header('Access-Control-Allow-Credentials', 'true');
$response->header('Access-Control-Max-Age', '86400');
}
return $response;
}
添加以后请求发现还是跨域原来我们用Nginx做负载Nginx给拒绝了在nginx加入
location /{
add_header Access-Control-Max-Age '86400';
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,Content-Length,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
}
很多同学处理跨域可能会发现我们的每次请求中都会发一个OPTIONS请求得知OPTIONS是浏览器发起的'preflight'请求,征求服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。但是我们发现每次这种情况都会触发OPTIONS请求,然后再去执行业务逻辑,虽然正常执行了,但是一个请求变成了两个,肯定增加了用户等待时间和服务器资源消耗。
Access-Control-Max-Age: 86400;表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。最后同一天内一个接口就只有一次OPTIONS请求了