解决Mixed Content: The page at https://* was loaded over HTTPS, but requested an insecure XMLHttpReque
问题:
前端页面调用后端接口加载不出来
原因分析:
通过查看浏览器调试 console 日志,得到报错如下
原文:
Mixed Content: The page at https://* was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint http://*. This request has been blocked; the content must be served over HTTPS
译文:
混合内容:https://*上的页面是通过HTTPS加载的,但是请求了一个不安全的XMLHttpRequest端点http://*.此请求已被阻止;内容必须通过HTTPS提供
结合业务场景:https协议的网站下请求http的资源
以及根据报错日志的问题描述:https协议的网站请求http协议的资源被浏览器认为不安全,请求被拦截
综合分析后得出结论:
发生该错误的原因由浏览器的安全机制引起的,一个最好的解决办法就是都是用http的请求,也免去了申请证书,但浏览器一直报不安全的话可能会散失一些用户。所以还是得安排上https协议,如果要请求的资源服务器支持https协议,我们只需要把请求的http改成https即可;如果不支持的话可以选择给资源服务器安排上ssl证书,但很多时候我们没办法自行更改资源服务器。
解决方案:
这个是在没法让资源方改为https时的下策
我们使用的是Nginx服务,因此可以利用Nginx的反向代理来解决该问题
这里先举个例子
例如 我们这边的网址是https://123.com 调用后端的网址是 http://456:77/api/xxx
这个时候直接调用是会报如上错误的,借用nginx的反向代理可以暂时绕过这个限制,即把后端接口地址替换为我们的https地址,然后通过反向代理来代理到http的地址上
具体操作如下:
1.在nginx中配置反向代理
将以下配置放置在http{}内
server { listen 443 ssl; # 你的域名 server_name 123.com; # 你的证书 crt对应的是公钥 key对应的是私钥 ssl_certificate xxxxx.crt; ssl_certificate_key xxxxx.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # 访问根路径跳转页面 # 如:https://123.com/ location / { root html; index index.html index.htm; } # 把后端http接口地址代理到当前前端部署的域名上 # 如:https://123.com/to_url location /to_url/ { proxy_pass http://456:77/; } }
重启nginx,使配置生效
2.修改前端调用地址
把原本的http://456:77/api/xxx 修改为 https://123.com/to_url/api/xxx,测试成功
后记:
其实这只是临时解决方案,因为会有问题,就是如果http://456:77/api/xxx 接口里引用的链接同样为http,还是会报错,虽然可以调用api接口了,但是可能会有部分显示不全
最好的方式还是让资源方也修改为https,才能解决根本问题!
这种方式对跨域问题也同样适用
No 'Access-Control-Allow-Origin' header is present on the requested resource.
同理,这种方式也适合解决跨域问题,当调用的接口为外部接口,被报跨域问题时,可以把外部接口代理在自有地址下,再调用
另外还有一个解决方案,适用于被调用方有https资源,但是自有代码地址未作https适配的方式
解决方案:
在我们的网站<head>标签里面加入如下内容即可:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
它会自动将HTTP请求升级成安全的HTTPS请求,网上的很多解决访问有问题,这个是一定可以的!
不过这个貌似有前提:
1、升级后的链接在服务器端必需有对应的资源。
2、只会升级网站内部的链接,对于不属于网站同部的链接,则保持默认状态。
3、并不是所以的浏览器兼容此 HTTP 请求头,兼容表如下
参考文档:
https://blog.csdn.net/qq_38238956/article/details/126059092
https://blog.csdn.net/weixin_40918067/article/details/117839199
https://blog.csdn.net/LuckyWinty/article/details/122593076