Laravel 7 AJAX身份认证请求返回Mixed Content错误排查
问题根因
你遇到的Mixed Content报错核心是Cloudflare Flexible SSL模式的特性导致的:
- Flexible模式下,Cloudflare到你的Apache服务端走HTTP协议,只有用户端到Cloudflare走HTTPS
- Laravel默认不信任代理请求携带的
X-Forwarded-Proto头,会将当前请求识别为HTTP协议,生成的所有链接、重定向地址默认都是HTTP开头 - HTTPS页面下请求HTTP资源就会触发浏览器的混合内容拦截,导致AJAX请求被中断,
.done()回调无法触发
解决方案按优先级执行
1. 配置Laravel信任Cloudflare代理
打开app/Http/Middleware/TrustProxies.php,修改配置如下:
protected $proxies = '*'; protected $headers = Request::HEADER_X_FORWARDED_ALL;
这一步会让Laravel正确读取Cloudflare传递的客户端真实协议(HTTPS),而不是用服务端本地的HTTP协议。
2. 强制全站生成HTTPS链接
打开app/Providers/AppServiceProvider.php,在boot方法中添加代码:
public function boot() { \URL::forceScheme('https'); }
彻底避免Laravel生成任何HTTP开头的链接。
3. 适配AJAX请求的响应逻辑
AJAX请求不适合直接返回302重定向,浏览器自动跟随重定向时会再次触发协议校验问题,改成AJAX请求返回JSON,前端手动处理跳转:
修改登录控制器的authenticated方法:
protected function authenticated(Request $request, $user) { if (auth()->user()->active) { $redirect = Session::get('current_page', '/'); if ($request->ajax()) { return response()->json([ 'code' => 0, 'redirect' => $redirect ]); } return redirect()->secure($redirect); } else { auth()->logout(); if ($request->ajax()) { return response()->json([ 'code' => 1, 'msg' => '账号未激活' ], 403); } return view('inactive_account'); } }
对应修改前端AJAX逻辑:
$.ajax({ url: '/login', type: "POST", data: { email: $('input[name="login"]').val(), password: $('input[name="password"]').val(), } }).fail(function (xhr) { if(xhr.responseJSON?.msg) { $('.alert-text').html(xhr.responseJSON.msg); return; } $('.alert-text').html('账号或密码错误'); }).done(function (res) { if(res.redirect) { window.location.href = res.redirect; } });
登出逻辑做同样的适配即可:判断如果是AJAX请求,返回带跳转地址的JSON,不要直接返回302重定向。
额外修复桌面端警告
桌面端的[Deprecation] Synchronous XMLHttpRequest警告是因为代码中存在设置了async: false的同步AJAX请求,找到对应代码去掉同步配置,改成默认的异步请求即可消除警告。
生效验证
修改完成后执行以下命令清理Laravel缓存即可测试:
php artisan config:clear php artisan route:clear
内容的提问来源于stack exchange,提问作者user194324
相关产品推荐
相关产品推荐

