简体   繁体   English

Android WebView 未加载 HTTPS URL

[英]Android WebView not loading an HTTPS URL

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    
}

When I try to load a URL in the WebBView it only shows a blank screen.当我尝试在 WebBView 中加载 URL 时,它只显示一个空白屏幕。 If I load Google.com or yahoo.com it's working fine.如果我加载 Google.com 或 yahoo.com 它工作正常。

Please visit this link: 请访问此链接:

Add this overriding method to your WebViewClient implementation.将此覆盖方法添加到您的 WebViewClient 实现。 You'll need to compile it with Android SDK 2.2 (API level 8) or later.您需要使用 Android SDK 2.2(API 级别 8)或更高版本对其进行编译。 The method appears in the public SDK as of 2.2 (API level 8) but we've tested it on devices running 2.1, 1.6 and 1.5 and it works on those devices too (so obviously the behaviour has been there all along).该方法出现在 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
}

this will help you.这会帮助你。

Per correct answer by fargth, follows is a small code sample that might help.根据 fargth 的正确答案,下面是一个可能有帮助的小代码示例。

First, create a class that extends WebViewClient and which is set to ignore SSL errors:首先,创建一个扩展 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
            }

}

Then with your web view object (initiated in the OnCreate() method), set its web view client to be an instance of the override class:然后使用您的 Web 视图对象(在 OnCreate() 方法中启动),将其 Web 视图客户端设置为覆盖类的实例:

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );

To properly handle SSL certificate validation and avoid application rejection from Google according new Security Policy, Change your code to invoke SslErrorHandler.proceed() whenever the certificate presented by the server meets your expectations, and invoke SslErrorHandler.cancel() otherwise.为了根据新的安全政策正确处理 SSL 证书验证并避免 Google 拒绝应用程序,请更改您的代码以在服务器提供的证书满足您的期望时调用 SslErrorHandler.proceed(),否则调用 SslErrorHandler.cancel()。

For example, I add an alert dialog to make user have confirmed and seems Google no longer shows warning.例如,我添加了一个警告对话框来让用户确认,似乎 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();
}

After this changes it will not show warning.在此更改后,它将不会显示警告。

override onReceivedSslError and remove覆盖 onReceivedSslError 并删除

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

And to solve Google security:并解决谷歌安全问题:

setDomStorageEnabled(true); setDomStorageEnabled(true);

Full code is:完整代码为:

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);

Copy and paste your code line bro , it will work trust me :) i am thinking ,you get a ssl error.复制并粘贴您的代码行兄弟,相信我,它会起作用:) 我在想,您收到了 ssl 错误。 İf you use override onReceivedSslError method and remove super it's super method.如果您使用覆盖 onReceivedSslError 方法并删除 super 它是 super 方法。 Just write handler.proceed() ,error will solve.只需编写 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());

I followed the answers above but still it seems not to be working for me below code did a trick for me when integrating payment gatways which are usually https requests :我遵循了上面的答案,但似乎仍然对我不起作用,下面的代码在集成通常是 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();
        }
    }
}

Above code is doing a post request in webview and redirecting to payment gateway.上面的代码在 webview 中执行 post 请求并重定向到支付网关。

Setting settings.setDomStorageEnabled(true);设置settings.setDomStorageEnabled(true); did a trick for me Hope this helps .为我做了一个技巧希望这会有所帮助。

To handle SSL urls the method onReceivedSslError() from the WebViewClient class, This is an example:要处理 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();
            }

        });

You can check my complete example here: https://github.com/Jorgesys/Android-WebView-Logging您可以在此处查看我的完整示例: https : //github.com/Jorgesys/Android-WebView-Logging

在此处输入图片说明

To solve Google security, do this:要解决 Google 安全问题,请执行以下操作:

Lines to the top:到顶部的行:

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

Code:代码:

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
    }
}

Recommended approach will be推荐的方法是

1. Don't call super method(Remove super call from overridden method) 1.不要调用超级方法(从重写的方法中删除超级调用)

2.Google recommend to call SslErrorHandler.cancel() method if any error comes 2.Google 建议在出现任何错误时调用SslErrorHandler.cancel()方法

3. Don't Prompt dialog to expose SSL errors 3.不要提示对话框暴露 SSL 错误

Whats the best solution??最好的解决办法是什么?? Remove this override method删除此覆盖方法

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

}

In case you want to use the APK outside the Google Play Store, eg, private a solution like the following will probably work:如果您想在 Google Play 商店之外使用 APK,例如,像下面这样的私有解决方案可能会起作用:

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

In case you want to add an additional optional layer of security, you can try to make use of certificate pinning .如果您想添加额外的可选安全层,您可以尝试使用证书锁定 IMHO this is not necessary for private or internal usage tough.恕我直言,这对于私人或内部使用来说不是必需的。

If you plan to publish the app on the Google Play Store, then you should avoid @Override onReceivedSslError(...){...}.如果您打算在 Google Play 商店上发布应用程序,那么您应该避免使用 @Override onReceivedSslError(...){...}。 Especially making use of handler.proceed().特别是使用 handler.proceed()。 Google will find this code snippet and will reject your app for sure since the solution with handler.proceed() will suppress all kinds of built-in security mechanisms .谷歌会找到这个代码片段并肯定会拒绝你的应用程序,因为使用 handler.proceed() 的解决方案将抑制各种内置安全机制

And just because of the fact that browsers do not complain about your https connection, it does not mean that the SSL certificate itself is trusted at all!并且仅仅因为浏览器不会抱怨您的 https 连接,这并不意味着 SSL 证书本身是完全可信的!

In my case, the SSL certificate chain was broken.就我而言, SSL 证书链已损坏。 You can quickly test such issues with SSL Checker or more intermediate with SSLLabs .您可以使用SSL Checker或使用SSLLabs来快速测试此类问题。 But please do not ask me how this can happen.但请不要问我这是怎么发生的。 I have absolutely no clue.我完全没有头绪。

Anyway, after reinstalling the SSL certificate, all errors regarding the " untrusted SSL certificate in WebView whatsoever " disappeared finally.无论如何,在重新安装 SSL 证书后,所有关于“ WebView 中不受信任的 SSL 证书”的所有错误最终消失了。 I also removed the @Override for onReceivedSslError(...) and got rid of handler.proceed() , and é voila my app was not rejected by Google Play Store (again).我还删除了 onReceivedSslError(...) 的 @Override 并删除了 handler.proceed() ,瞧我的应用程序没有被 Google Play 商店拒绝(再次)。

My website is a subdomain which is developed on angular 8 which is also using localstorage and cookies.我的网站是一个在 angular 8 上开发的子域,它也使用 localstorage 和 cookie。 website showed after setting the below line, along with other solutions mentioned above.设置以下行后显示网站,以及上面提到的其他解决方案。

webSettings.setDomStorageEnabled(true);

Setting thoses two properties were enough to make it work for me, and doesn't expose to security issues :设置这两个属性足以使其对我有用,并且不会暴露于安全问题:

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

Use this line webview.getSettings().setDomStorageEnabled(true) in your java code在您的 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);

add android:usesCleartextTraffic="true" in application tag in manifest all will be ok .在清单的应用程序标签中添加 android:usesCleartextTraffic="true" 一切正常。 this works for me.这对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM