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();
我有一个解决方案,我的 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();