Android WebView не завантажує URL-адресу HTTPS


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    
}

Коли я намагаюся завантажити URL-адресу в WebBView, вона відображає лише порожній екран. Якщо я завантажую Google.com або yahoo.com, він працює нормально.


1
це працює, я перевірив зараз. перевірте ще раз, якщо після цього не працює, додайте це за допомогою коду webView.getSettings (). setUseWideViewPort (true); webView.getSettings (). setLoadWithOverviewMode (істина);
ilango j

Відповіді:


155

Будь ласка, перейдіть за цим посиланням:

Додайте цей метод перевизначення до реалізації WebViewClient. Вам потрібно буде скомпілювати його з Android SDK 2.2 (рівень API 8) або пізнішої версії. Метод з'являється у загальнодоступному SDK станом на 2.2 (рівень API 8), але ми протестували його на пристроях з версіями 2.1, 1.6 та 1.5, і він також працює на цих пристроях (тому очевидно, що поведінка була там увесь час).

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

це вам допоможе.


3
Останній запис у дискусії спрацював чудово. Дуже дякую.
Білл Лахті,

54
Попередження про безпеку : Зверніть увагу, що це повністю перешкоджає тому, що в першу чергу є SSL.
там

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.
Густаво,

3
Будь-хто знає, як вирішити попередження Google Security, якщо так, будь ласка, дайте мені знати, тому що я також стикаюся з цією проблемою.
Pratik Tank

49

Відповідно до правильної відповіді fargth, наводиться невеликий зразок коду, який може допомогти.

Спочатку створіть клас, який розширює 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
            }

}

Потім за допомогою об’єкта веб-перегляду (ініційованого методом OnCreate ()) встановіть його клієнт веб-перегляду як екземпляр класу заміни:

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );

2
це дає попередження безпеки Google: небезпечна реалізація обробника WebViewClient.onReceivedSslError. ти знаєш, як це вирішити?
Pratik Tank

2
Google позначив додаток як ненадійний у магазині, як це зробити без ssl?
Ajay Pandya

Не використовуйте метод Super- super.onReceivedSslError (подання, обробник, помилка);
Атул

41

Щоб правильно обробляти перевірку сертифіката 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 знайшов якесь рішення щодо запуску програми в магазині ігор?
Кеша,

2
Я реалізував зворотний виклик onReceivedSslError, як запропоновано. Після цього додаток було опубліковано успішно.
Vivek Sinha

11

Видаліть наведений нижче код, він буде працювати

 super.onReceivedSslError(view, handler, error);

Чудово, у мене це вийшло. Ви можете пояснити, як це працювало?
Arth Tilva

3
@ArthTilva з google docs: "поведінка за замовчуванням - скасувати завантаження". Зателефонувавши супер, ви викликаєте таку поведінку за замовчуванням, перш ніж вона зможе досягти решти методу. developer.android.com/reference/android/webkit/…
Джош Лейрд

11

перевизначити onReceivedSslError і видалити

super.onReceivedSslError (подання, обробник, помилка)

А для вирішення питань безпеки Google:

setDomStorageEnabled (істина);

Повний код:

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 (подання, обробник, помилка) спрацювало у мене.
Даніш Шерма,

7

Скопіюйте та вставте свій рядок коду, брат, це буде працювати, повірте мені :) я думаю, ви отримаєте помилку ssl. Якщо ви використовуєте перевизначення методу onReceivedSslError і видаляєте супер, це супер метод. Просто напишіть 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), Google Play відхилить вашу заявку.
Alp Altunel,

У мене занадто багато додатків у Google Play, жодна програма все одно не отримує відхилення.
ozanurkan

1
відхилить слова від січня 2020 року
Джон Рубан Сінгх,

6

Для обробки URL-адрес SSL використовується метод onReceivedSslError () з класу WebViewClient, Це приклад:

 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. Куди мені це покласти? :)
Гедимін

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

Наведений вище код робить запит на публікацію в веб-перегляді та перенаправляє на платіжний шлюз.

Налаштування settings.setDomStorageEnabled(true);зробило для мене фокус. Сподіваюся, це допоможе.


2
Це рішення ПОЛНО відключає перевірку сертифіката, залишаючи відкритим для атак "людина посередині". Цього ви ніколи не повинні робити, ОСОБЛИВО для платіжних шлюзів.
Dirbaio

Для мене спочатку веб-перегляд не завантажував вміст, а лише фонове зображення сторінки. Після того, як я просто додав, webview.getSettings.setDomStorageEnabled(true);це магічно спрацювало. Можливо, веб-сторінка використовує якийсь API HTML 5, тож увімкнення DomStorage спрацювало для мене.
Ішант Сагар,

handler.proceed () в обхід SSL
Джон Рубан Сінгх

що таке Encodingutil.getbyte
Akash kumar

2

Рекомендований підхід буде

1. Не називайте супер метод (Вилучити супервиклик із перевизначеного методу)

2.Google рекомендує зателефонувати до SslErrorHandler.cancel () якщо виникає помилка

3. Не підказувати діалогове вікно для виявлення помилок SSL

Що найкраще рішення? Видаліть цей метод заміни

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

}

Ви просите рішення чи пропонуєте?
Дхарман,

Я пропоную такий підхід
Джон Рубан Сінгх,

@JohnRubanSingh Привіт Джон, я завантажую файл JS з активів, а після завантаження файлу onPageFinished я викликаю функцію всередині JS. Отже, перевизначення onReceivedSslError () необхідне, оскільки я використовую webview.setWebViewClient (new ....)?
Шивам Шарма

Цей код відхиляє мій APK. Навіть з 9 місяців цей код не спричиняє відхилення, а раптом стикається з відхиленнями r8. перемикач (error.getPrimaryError ()) {case SslError.SSL_UNTRUSTED: handler.proceed (); перерву; справа SslError.SSL_EXPIRED: справа SslError.SSL_IDMISMATCH: справа SslError.SSL_NOTYETVALID: справа SslError.SSL_DATE_INVALID: справа SslError.SSL_INVALID: за замовчуванням: handler.c; перерву; }
Шивам Шарма

@JohnRubanSingh, будь ласка, допоможіть мені. Ми можемо приєднатися на слабі.
Шивам Шарма

0

Налаштування двох властивостей було достатньо, щоб це працювало для мене, і це не піддає проблемам безпеки:

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

0

Використовуйте цей рядок webview.getSettings (). SetDomStorageEnabled (true) у вашому коді Java

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

0

Якщо ви хочете використовувати APK поза магазином Google Play, наприклад, приватне рішення, як показано нижче, можливо, буде працювати:

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

Якщо ви хочете додати додатковий необов’язковий рівень безпеки, ви можете спробувати скористатися закріпленням сертифіката . IMHO це не потрібно для жорсткого приватного або внутрішнього використання.

Якщо ви плануєте опублікувати програму в Google Play Store, вам слід уникати @Override onReceivedSslError (...) {...}. Особливо використовуючи handler.proceed (). Google знайде цей фрагмент коду і точно відхилить вашу програму, оскільки рішення з handler.proceed () придушить всі види вбудованих механізмів безпеки .

І лише через те, що браузери не скаржаться на ваше з’єднання https, це не означає, що самому сертифікату SSL взагалі довіряють!

У моєму випадку ланцюжок сертифікатів SSL був розірваний. Ви можете швидко протестувати такі проблеми за допомогою SSL Checker або більш проміжних з SSLLabs . Але, будь ласка, не питайте мене, як це може статися. Я абсолютно не маю поняття.

У будь-якому випадку, після переінсталяції сертифіката SSL усі помилки щодо " ненадійного сертифіката SSL у WebView whatsorely " остаточно зникли. Я також видалив @Override для onReceivedSslError (...) і позбувся handler.proceed () , і é voila мій додаток не був відхилений Google Play Store (знову).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.