从后台启动混合 Android 应用程序时 HTTP 调用中的奇怪行为
Weird behaviour in HTTP call when hybrid Android app is launched from background
问题的标题可能被认为是不是一个有效的问题,但我们已经花了 4-5 天的时间来调试这个问题。这是上下文:
- 我们有一个混合应用程序 (Ionic3 + Cordova)
- 我们在欧洲有一家电信网络运营商
- 我们已经为他们提供了一个要列入白名单的 URL,当用户使用该运营商的移动网络
- URL 必须是 http URL 而不是 https
- 所以我们在我们的代码库中添加了一个 Angular HTTP 拦截器,仅针对 URL
将 https 转换为 http
- Android 移动应用会在应用启动后立即点击 URL
现在是working/expected行为:
当应用程序刚启动时(不在后台或被主屏幕杀死),应用程序点击 URL 并且网络运营商识别 URL 我们收到手机号码用户。
这是不工作的场景:
现在,我们按下 Android 中的后退按钮并优雅地退出应用程序。这意味着 Android 应用程序在后台并被杀死。现在我们再次从应用程序的图标启动应用程序,header 充实不起作用。
现在,我们使用 tcpflow
命令添加了各种 tcp 级别的日志:
sudo tcpflow -i eth0 port 443 -C -e http
sudo tcpflow -i eth0 port 80 -C -e http
而且我们发现,无论何时从后台重新启动该应用程序(因此会触发 URL),整个请求都会被加密,但 URL我们 接收到的是 http URL 并且 端口是 443.
我们在我们的 http 拦截器和 Android phone 中添加了各种日志,但我们无法确定根本原因。有人可以指出不同的方向来寻找问题。
编辑 1:
- 在具有不同 Android OS 和设备制造商
的 5 种不同设备上进行了测试
- Android 应用是 release build
经过一整天的研究,我终于找出了这个问题的根本原因。
这里我根据线索得到了问题(以防有人从中得到帮助):
- 我开始了解
launchMode
类型的 Android 应用程序
- 我用 Android 的
launchMode
和这个 http 加密 盯着谷歌搜索
- 我登陆了博客 post 正在阅读 Android O to drop insure TLS version fallback
- 我在 Google 上搜索了更多关于 TLS 版本回退
- 谷歌搜索不同的关键字,将我带到 Android 8.0 Behavior Changes,在那里我读到了 网络和 HTTP(S) 连接,在那里我看到了一个新概念(对我来说),即 TLS重新谈判。
- 我开始阅读有关 TLS 重新协商的内容,并开始将它与
Nginx
联系起来,它是更改日志,所以我发现这与 Nginx 和 HTTP 通信有关。
- 到目前为止,我只是在查看 Nginx 服务器配置中的 HTTP 块,但我查看了 Nginx 中的 HTTPs 块,发现(对我来说)不清楚 header 配置
Strict-Transport-Security
被设置为 max-age=31536000 always
- 我仔细研究了这个 header 配置,整个问题在我脑海中立即得到了解决,这不是问题,这是默认行为,当浏览器看到成功的 HTTPs 请求并看到 header,下一个 non-HTTP 请求默认尝试使用 HTTP,这就是我们遇到的问题。
我删除了 header(首先将其值减少到仅 10 毫秒,以便浏览器可以生效)并使用相同的场景测试我的应用程序,一切都按预期开始工作。
问题的标题可能被认为是不是一个有效的问题,但我们已经花了 4-5 天的时间来调试这个问题。这是上下文:
- 我们有一个混合应用程序 (Ionic3 + Cordova)
- 我们在欧洲有一家电信网络运营商
- 我们已经为他们提供了一个要列入白名单的 URL,当用户使用该运营商的移动网络
- URL 必须是 http URL 而不是 https
- 所以我们在我们的代码库中添加了一个 Angular HTTP 拦截器,仅针对 URL 将 https 转换为 http
- Android 移动应用会在应用启动后立即点击 URL
现在是working/expected行为:
当应用程序刚启动时(不在后台或被主屏幕杀死),应用程序点击 URL 并且网络运营商识别 URL 我们收到手机号码用户。
这是不工作的场景:
现在,我们按下 Android 中的后退按钮并优雅地退出应用程序。这意味着 Android 应用程序在后台并被杀死。现在我们再次从应用程序的图标启动应用程序,header 充实不起作用。
现在,我们使用 tcpflow
命令添加了各种 tcp 级别的日志:
sudo tcpflow -i eth0 port 443 -C -e http
sudo tcpflow -i eth0 port 80 -C -e http
而且我们发现,无论何时从后台重新启动该应用程序(因此会触发 URL),整个请求都会被加密,但 URL我们 接收到的是 http URL 并且 端口是 443.
我们在我们的 http 拦截器和 Android phone 中添加了各种日志,但我们无法确定根本原因。有人可以指出不同的方向来寻找问题。
编辑 1:
- 在具有不同 Android OS 和设备制造商 的 5 种不同设备上进行了测试
- Android 应用是 release build
经过一整天的研究,我终于找出了这个问题的根本原因。
这里我根据线索得到了问题(以防有人从中得到帮助):
- 我开始了解
launchMode
类型的 Android 应用程序 - 我用 Android 的
launchMode
和这个 http 加密 盯着谷歌搜索
- 我登陆了博客 post 正在阅读 Android O to drop insure TLS version fallback
- 我在 Google 上搜索了更多关于 TLS 版本回退
- 谷歌搜索不同的关键字,将我带到 Android 8.0 Behavior Changes,在那里我读到了 网络和 HTTP(S) 连接,在那里我看到了一个新概念(对我来说),即 TLS重新谈判。
- 我开始阅读有关 TLS 重新协商的内容,并开始将它与
Nginx
联系起来,它是更改日志,所以我发现这与 Nginx 和 HTTP 通信有关。 - 到目前为止,我只是在查看 Nginx 服务器配置中的 HTTP 块,但我查看了 Nginx 中的 HTTPs 块,发现(对我来说)不清楚 header 配置
Strict-Transport-Security
被设置为max-age=31536000 always
- 我仔细研究了这个 header 配置,整个问题在我脑海中立即得到了解决,这不是问题,这是默认行为,当浏览器看到成功的 HTTPs 请求并看到 header,下一个 non-HTTP 请求默认尝试使用 HTTP,这就是我们遇到的问题。
我删除了 header(首先将其值减少到仅 10 毫秒,以便浏览器可以生效)并使用相同的场景测试我的应用程序,一切都按预期开始工作。