背景:android中引入的html页面是http请求(web服务仅开放了80端口),但html页面引用的后端接口是https请求,则发生android中html页面请求接口异常<请求无法发送到后端服务(status=0)>。
浏览器出于安全考虑,要求: 同源策略(Same-Origin Policy, SOP)
- 协议(Protocol):如
http
或https
- 域名(Host):如
www.example.com
- 端口(Port):如
80
(HTTP 默认)、443
(HTTPS 默认)或自定义端口如8080
只有当 协议、域名、端口 三者完全一致时,才被认为是同源,否则就是跨域。
Android WebView(基于 Chromium 内核)遵循浏览器安全策略:
HTTPS 页面 → 调用 HTTP 接口 = 不安全,通常直接被拦截。
HTTP 页面 → 调用 HTTPS 接口 = 视为 跨域 + mixed content,也可能被拦截,尤其在高版本 Android。
✅ 解决方案
方案 1:让 HTML 页面也用 HTTPS (推荐)
最干净的解决方案就是把 HTML 页面本身部署在 HTTPS 上。
这样整个页面和接口都在 HTTPS 下,就不会触发浏览器/内核的 mixed content 限制。
方案 2:WebView 设置允许混合内容
如果后端暂时不能改,可以在 Android WebView 里允许 Mixed Content。
WebSettings webSettings = webView.getSettings(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // MIXED_CONTENT_ALWAYS_ALLOW:允许 http 和 https 混用 webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); }
⚠️ 缺点:降低安全性(可能被劫持 http 请求)。
一般仅用于过渡方案。
方案 3:反向代理(推荐给你当前情况)
把 HTTP 页面请求 和 HTTPS 接口 统一到同一个协议。
比如在 Nginx 配置里:
页面继续用
http://cloud.amardata.com/...
接口请求
http://cloud.amardata.com/api/...
然后由 Nginx 反向代理转发到后端
https://cloud.amardata.com/api/...
这样页面和接口都是 http://
,浏览器不会阻止,但对后端仍然是安全的 https://
。
方案 4:通过 Android 端代理接口
如果 HTML 不能改,可以让 Android 端 拦截 WebView 的接口请求,转为 App 内部请求,再把结果注入页面。
用
WebViewClient.shouldInterceptRequest()
来拦截请求。自己用
OkHttp/HttpURLConnection
发起请求,返回给 WebView。
📝 总结
你遇到的问题就是 混合内容被 Android WebView 拦截:
✅ 最推荐:页面和接口都改成 HTTPS
⚠️ 临时方案:
setMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW)
🚀 企业常用:用 Nginx 反向代理,让页面和接口保持同协议