现象:在https网页下,发送http请求,会在控制台报错,网页的一些功能可能会异常,如:
Mixed Content: The page at 'https://10.124.**.**/#/embeddedPage?linkUrl=https%3A%2F%2F10.124.**.**%2Fkite-react%2F%23%2Freception&systemInfoId=10085&menuActiveKey=329&usePortalFoot=false'
was loaded over HTTPS, but requested an insecure resource 'http://10.124.**.**/auth/attachment/subOppoDownload?flowId=b2b984282b1527d2544e7d807a33e38d&userLogin=hq'.
This request has been blocked; the content must be served over HTTPS
本文档将围绕以下几点进行阐述
1、造成报错原因
浏览器不允许在https页面里嵌入http的请求,现在高版本的浏览器为了用户体验,都不会弹窗报错,只会在控制台上打印一条错误信息。
报Mixed Content的前提条件:
1、在https网页下;
2、请求接口为http请求,但请求的服务器又升级为https协议了。
2、解决方法主要有两个
2.1、在客户端主页面的head中加入下面代码(将调用的http请求升级成https请求并调用)
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
2.2、由后端在服务器上设置响应头,如nginx上设置如下配置:
add_header Content-Security-Policy upgrade-insecure-requests;
以上两种方法有细微的区别。客户端设置的这种方法会将所有接收https请求的服务接口全部自动升级为https请求,即使在代码中请求http://www.baidu.com, 最终在浏览器网络请求中查看,会看到https://www.baidu.com。
对于接收非https请求的服务接口,则上述设置无效,不会自动升级为https请求。如下图所示:
优劣:对于一般情况,客户端或者服务器端设置都没有太大区别。但对于下面的情况,则只能选则服务端设置。
如果设置客户端方式,假设有A(https)、B(http)两个接口,但B所在服务器也设置了https代理(所以最终B接口会升级为https请求),但https代理转发没有设置B接口,则B接口会报net::ERR_SSL_PROTOCOL_ERROR错误。
如果设置服务端方式,则只需在A接口对应的服务器上设置响应头,在B服务器上不做设置,则B接口正常请求到http代理上,能正确找到http接口。
3、实战分析
说明:localhost/api/getData接口为http接口,www.loma18.com/blog/getArticleTypeCount 为https接口。
正确写法如下:
axios.get('http://localhost/api/getData'); // 特殊请求,需访问http接口
axios.get('//www.loma18.com/blog/getArticleTypeCount'); // 一般请求,全部升级为https请求
4、问题分析
对于以下跨域问题,可通过在nginx设置 add_header Access-Control-Allow-Origin *;