Android WebView 阻止从 https 重定向到 http

Android WebView blocks redirect from https to http

我有一个解决方案,我的 Android WebView 需要先打开一个 https url,然后它会被重定向到一个 http url(它可能正在尝试一个 http POST 来自 https 站点)。这不起作用,我的 Android 调试日志显示:

02-20 11:04:45.079 8538-8538/? E/WebViewCallback﹕ Blocked URL: [blocked] The page at 'https://xxx/' was loaded over HTTPS, but is submitting data to an insecure location at 'http://yyy': this content should also be submitted over HTTPS.

WebView 中是否有允许此行为的任何配置选项?

更多信息:这似乎是 Android SDK 中的行为更改。很久以前编译的客户端没有任何抱怨。

您可以通过覆盖 onReceivedSslError() 方法来忽略 ssl 错误。

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    handler.proceed(); // Ignore SSL certificate errors
}

希望对你有用。

根据我的研究,我认为无法禁用此功能。我将在这两个站点中支持 https。反正最安全。

Lollipop (API 20) 中混合 http/https 内容的默认 WebView 设置发生了变化。有关详细信息,请参阅 https://datatheorem.github.io/android/2014/12/20/webviews-andorid-lollipop/

要允许 https 重定向到 http,您需要将混合内容模式设置为 MIXED_CONTENT_ALWAYS_ALLOW

 if (Build.VERSION.SDK_INT >= 21) {
        webview.getSettings().setMixedContentMode( WebSettings.MIXED_CONTENT_ALWAYS_ALLOW );
    }

请注意,从安全角度来看,设置 MIXED_CONTENT_ALWAYS_ALLOW 很糟糕,正如您在回答中指出的那样,最好在两个站点上都支持 https。

但对于那些无法控制网站的人来说,这应该可行。

对我有用

 AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.webView.getContext());
  AlertDialog alertDialog = builder.create();
  String message = "Certificate error.";
  switch (error.getPrimaryError()) {
     case SslError.SSL_UNTRUSTED:
        message = "The certificate authority is not trusted.";
        break;
     case SslError.SSL_EXPIRED:
        message = "The certificate has expired.";
        break;
     case SslError.SSL_IDMISMATCH:
        message = "The certificate Hostname mismatch.";
        break;
     case SslError.SSL_NOTYETVALID:
        message = "The certificate is not yet valid.";
        break;
  }
  message += " Do you want to continue anyway?";
  alertDialog.setTitle("SSL Certificate Error");
  alertDialog.setMessage(message);
  alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {

     public void onClick(DialogInterface dialog, int which) {
        Log.d("CHECK", "Button ok pressed");
        // Ignore SSL certificate errors
        handler.proceed();
     }
  });
  alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {

     public void onClick(DialogInterface dialog, int which) {
        Log.d("CHECK", "Button cancel pressed");
        handler.cancel();
     }
  });
  alertDialog.show();