Android WebView未加载HTTPS URL


91
public void onCreate(Bundle savedInstance)
{       
    super.onCreate(savedInstance);
    setContentView(R.layout.show_voucher);
    webView=(WebView)findViewById(R.id.webview);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setBuiltInZoomControls(true);
    String url ="https://www.paymeon.com/Vouchers/?v=%C80%8D%B1x%D9%CFqh%FA%84%C35%0A%1F%CE&iv=%25%EE%BEi%F4%DAT%E1"
    //webView.loadUrl(url); // Not Working... Showing blank
    webView.loadUrl("http://www.yahoo.com"); // its working    
}

当我尝试在WebBView中加载URL时,它仅显示空白屏幕。如果我加载Google.com或yahoo.com,则工作正常。


1
它正在工作,我现在检查了。再次检查是否不起作用,然后在代码中添加代码webView.getSettings()。setUseWideViewPort(true); webView.getSettings()。setLoadWithOverviewMode(true);
ilango j 2011年

Answers:


154

请访问此链接:

将此替代方法添加到您的WebViewClient实现中。您需要使用Android SDK 2.2(API级别8)或更高版本进行编译。该方法从2.2(API级别8)开始出现在公共SDK中,但是我们已经在运行2.1、1.6和1.5的设备上对其进行了测试,并且也可以在这些设备上运行(因此,这种行为一直存在)。

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

这将为您提供帮助。


3
讨论中的最后一个条目效果很好。非常感谢。
Bill Lahti

54
安全警告:请注意,这样做完全不利于实现SSL的目的。
ereOn 2014年

8
请不要这样做。这是不安全的,并且不允许在Play商店中使用。

33
Google现在会向实施上述解决方案的任何人发送电子邮件:Your app(s) listed at the end of this email have an unsafe implementation of the WebViewClient.onReceivedSslError handler. Specifically, the implementation ignores all SSL certificate validation errors, making your app vulnerable to man-in-the-middle attacks. Apps with vulnerabilities that expose users to risk of compromise may be considered Dangerous Products in violation of the Content Policy and section 4.4 of the Developer Distribution Agreement.
Gustavo 2015年

3
任何人都知道如何解决Google安全警告,如果是,请让我知道,因为我也面临这个问题。
Pratik Tank

48

根据正确的答案,下面是一个可能有用的小代码示例。

首先,创建一个扩展WebViewClient的类并将其设置为忽略SSL错误:

// SSL Error Tolerant Web View Client
private class SSLTolerentWebViewClient extends WebViewClient {

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

}

然后,使用您的Web视图对象(在OnCreate()方法中启动),将其Web视图客户端设置为重写类的实例:

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );

2
这给出了谷歌的安全警告:WebViewClient.onReceivedSslError处理程序的不安全实现。你知道如何解决吗?
Pratik Tank

2
Google在Play商店上将该应用标记为“不saisaif”,如果没有ssl怎么办?
Ajay Pandya

不要使用Super方法-super.onReceivedSslError(view,handler,error);
Atul Bhardwaj

40

为了正确处理SSL证书验证并避免根据新的安全策略拒绝来自Google的应用程序,请更改代码以在服务器提供的证书满足您的期望时调用SslErrorHandler.proceed(),否则,请调用SslErrorHandler.cancel()。

例如,我添加了一个警报对话框,以使用户已经确认,并且似乎Google不再显示警告。

    @Override
    public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    String message = "SSL 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?";

        builder.setTitle("SSL Certificate Error");
        builder.setMessage(message);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}

更改之后,它不会显示警告。


如果我从实现中删除onReceivedSslError块,将会发生什么?
Vivek Sinha

1
@VivekSinha它将调用handler.cancel(); 默认。
Anant Shah

1
但是Google仍然拒绝我的应用说同样的原因。为什么?
Vivek Sinha

@VivekSinha找到了有关在Play商店中启动应用的任何解决方案?
Kesha

2
我按照建议实现了onReceivedSslError回调。应用已成功发布。
Vivek Sinha


11

覆盖onReceivedSslError并删除

super.onReceivedSslError(视图,处理程序,错误)

并解决Google安全问题:

setDomStorageEnabled(true);

完整的代码是:

webView.enableJavaScript();
webView.getSettings().setDomStorageEnabled(true); // Add this
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebViewClient(new WebViewClient(){
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            // DO NOT CALL SUPER METHOD
            super.onReceivedSslError(view, handler, error);
        }
    });

非常感谢你 删除super.onReceivedSslError(view,handler,error)对我有用。
丹麦夏尔马

7

复制并粘贴您的代码行bro,请相信我:)我在想,您会收到ssl错误。如果您使用重写onReceivedSslError方法并删除super,则它是super方法。只需编写handler.proceed(),错误就会解决。

    webView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress) {

            activity.setTitle("Loading...");
            activity.setProgress(progress * 100);

            if (progress == 100)
                activity.setTitle(getResources().getString(R.string.app_name));
        }
    });

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Log.d("Failure Url :" , failingUrl);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            Log.d("Ssl Error:",handler.toString() + "error:" +  error);
            handler.proceed();
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    });
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setLoadWithOverviewMode(true);
    webView.getSettings().setUseWideViewPort(true);
    webView.getSettings().setDomStorageEnabled(true);
    webView.loadUrl(Constant.VIRTUALPOS_URL + "token=" + Preference.getInstance(getContext()).getToken() + "&dealer=" + Preference.getInstance(getContext()).getDealerCode());

谢谢。致电handler.proceed()onReceivedSslError拯救我的一天
Tam Huynh,

2
如果您这样做(现在是2019年7月),则Google Play将拒绝您的申请。
Alp Altunel

İ在Google Play上有太多的应用程序,没有应用程序仍然被拒绝。
ozanurkan '19

1
将会拒绝2020年1月的建议
John Ruban Singh

6

要处理SSL url ,请使用WebViewClient类中的onReceivedSslError()方法 ,这是一个示例:

 webview.setWebViewClient(new WebViewClient() {
              ...
              ...
              ...

            @Override
            public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
                String message = "SSL 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 += "\"SSL Certificate Error\" Do you want to continue anyway?.. YES";

                handler.proceed();
            }

        });

您可以在此处查看我的完整示例:https//github.com/Jorgesys/Android-WebView-Logging

在此处输入图片说明


6

要解决Google安全问题,请执行以下操作:

顶行:

import android.webkit.SslErrorHandler;
import android.net.http.SslError;

码:

class SSLTolerentWebViewClient extends WebViewClient {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        if (error.toString() == "piglet")
            handler.cancel();
        else
            handler.proceed(); // Ignore SSL certificate errors
    }
}

2
我是Android新手。我该放在哪里?:)
Gediminas '18

5

我遵循了上面的答案,但是在集成通常是https请求的支付网关时,以下代码似乎对我不起作用:

public class MainActivity extends Activity {

    WebView webView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = (WebView) findViewById(R.id.webView1);
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setDomStorageEnabled(true);
        webView.setWebViewClient(new MyWebViewClient());
        String postData = "amount=1000&firstname=mtetno&email=mttee@gmail.com&phone=2145635784&productinfo=android&surl=success.php"
                + "&furl=failure.php&lastname=qwerty&curl=dsdsd.com&address1=dsdsds&address2=dfdfd&city=dsdsds&state=dfdfdfd&"
                + "country=fdfdf&zipcode=123456&udf1=dsdsds&udf2=fsdfdsf&udf3=jhghjg&udf4=fdfd&udf5=fdfdf&pg=dfdf";
        webView.postUrl(
                "http://host/payment.php",
                EncodingUtils.getBytes(postData, "BASE64"));

    }

    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            webView.loadUrl(url);
            return true;
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                SslError error) {
            handler.proceed();
        }
    }
}

上面的代码在webview中执行发布请求,并重定向到支付网关。

设置settings.setDomStorageEnabled(true);对我来说是个窍门,希望这会有所帮助。


2
此解决方案完全禁用证书验证,从而使您容易受到中间人攻击。这是您永远都不应做的事情,尤其是对于支付网关而言。
Dirbaio

对我而言,最初Webview并不是加载内容,而是页面的背景图片。在我刚刚添加之后,webview.getSettings.setDomStorageEnabled(true);它神奇地工作了。也许网页正在使用某种HTML 5 API,所以启用DomStorage对我来说很有用。
Ishant Sagar

handler.proceed()绕过SSL
John Ruban Singh,

什么是Encodingutil.getbyte
Akash kumar,

2

推荐的方法是

1. 不要调用超级方法(从重写的方法中删除超级调用)

2. 如果出现任何错误,Google建议调用SslErrorHandler.cancel()方法

3. “不提示”对话框公开SSL错误

什么是最好的解决方案? 删除此替代方法

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error) {

}

您是要寻求解决方案还是提出建议?
Dharman

我建议采用这种方法
John Ruban Singh,

@JohnRubanSingh约翰,您好,我从资产中加载了一个JS文件,并在使用onPageFinished加载文件后,在JS中调用了一个函数。因此,当我使用webview.setWebViewClient(new ....)时,必须重写onReceivedSslError()吗?
Shivam Sharma

此代码拒绝了我的APK。即使9个月以来,此代码也不会导致拒绝,但现在突然面临拒绝r8。开关(error.getPrimaryError()){case SslError.SSL_UNTRUSTED:handler.proceed(); 打破; case SslError.SSL_EXPIRED:case SslError.SSL_IDMISMATCH:case SslError.SSL_NOTYETVALID:case SslError.SSL_DATE_INVALID:case SslError.SSL_INVALID:默认值:handler.cancel(); 打破; }
Shivam Sharma

@JohnRubanSingh请帮助我。我们可以放松一下。
Shivam Sharma

0

设置这两个属性足以使其对我有用,并且不会暴露出安全问题:

 WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setDomStorageEnabled(true);

0

在您的Java代码中使用以下代码行webview.getSettings()。setDomStorageEnabled(true)

WebView webView = (WebView) findViewById(R.id.webview);    
webView.getSettings().setDomStorageEnabled(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl(yourUrl);

0

如果您想在Google Play商店外使用APK,例如将以下私有解决方案私有化,则可能会起作用:

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

如果您要添加其他可选的安全层,可以尝试使用证书固定。恕我直言,这对于私人或内部使用非常困难。

如果您打算在Google Play商店上发布该应用程序,则应避免@Override onReceivedSslError(...){...}。特别是利用handler.proceed()。Google会找到此代码段,并确定会拒绝您的应用程序,因为使用handler.proceed()的解决方案将禁止所有内置的安全机制

仅仅因为浏览器不抱怨您的https连接这一事实,并不意味着SSL证书本身是完全受信任的!

就我而言,SSL证书链已损坏。您可以使用SSL Checker或使用SSLLabs的更多中间件快速测试此类问题。但是请不要问我这是怎么发生的。我完全不知道。

无论如何,在重新安装SSL证书后,有关“ WebView不受信任的SSL证书 ”的所有错误最终消失了。我还删除了onReceivedSslError(...)的@Override并摆脱了handler.proceed(),瞧瞧我的应用程序也未被Google Play商店拒绝。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.