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, он работает нормально.

sumit
источник
1
он работает, я проверил сейчас. проверьте еще раз, если после этого не работает, добавьте это в свой код webView.getSettings (). setUseWideViewPort (true); webView.getSettings (). setLoadWithOverviewMode (истина);
ilango j

Ответы:

156

Посетите эту ссылку:

Добавьте этот метод переопределения в свою реализацию 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
Последняя запись в обсуждении отлично сработала. Огромное спасибо.
Билл Лахти
55
Предупреждение системы безопасности : обратите внимание, что это полностью лишает смысла использование SSL.
ereOn
8
Пожалуйста, не делай этого. Это небезопасно и запрещено в Play Store.
Сурьма
34
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, если да, дайте мне знать, потому что я тоже столкнулся с этой проблемой.
Pratik Tank
49

Для правильного ответа ниже приводится небольшой пример кода, который может помочь.

Сначала создайте класс, который расширяет 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 пометил приложение как Unsaif в игровом магазине, как это можно сделать без ssl?
Аджай Пандья,
Не используйте метод 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?
Вивек Синха
1
@VivekSinha вызовет handler.cancel (); по умолчанию.
Anant Shah
1
но Google по-прежнему отклонил мое приложение по той же причине. Зачем?
Вивек Синха
@VivekSinha нашла какое-нибудь решение относительно запуска приложения в игровом магазине?
Кеша
2
Я реализовал обратный вызов onReceivedSslError, как было предложено. После этого приложение было успешно опубликовано.
Вивек Синха
11

Удалите приведенный ниже код, он будет работать

 super.onReceivedSslError(view, handler, error);
Король масс
источник
Отлично, у меня это сработало. Не могли бы вы объяснить, как это работало?
Arth Tilva 06
3
@ArthTilva из документации Google: «поведение по умолчанию - отменить загрузку». Вызывая super, вы вызываете это поведение по умолчанию, прежде чем оно достигнет остальной части метода. 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. Если вы используете метод override 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 () в onReceivedSslErrorsave my day
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

введите описание изображения здесь

Jorgesys
источник
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
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
Это решение ПОЛНОСТЬЮ отключает проверку сертификата, оставляя вас уязвимыми для атак типа «злоумышленник в середине». Этого никогда не следует делать, ОСОБЕННО для платежных шлюзов.
Дирбайо 01
Для меня изначально веб-просмотр не загружал контент, а только фоновое изображение страницы. После того, как я просто добавил, webview.getSettings.setDomStorageEnabled(true);это волшебным образом сработало. Возможно, на веб-странице используется какой-то HTML 5 API, поэтому включение DomStorage у меня сработало.
Ishant Sagar
handler.proceed () в обход SSL
Джон Рубан Сингх
что такое Encodingutil.getbyte
Акаш Кумар
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 (новый ....)?
Шивам Шарма
Этот код отклоняет мой 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: default: handler.cancel (); перемена; }
Шивам Шарма
@JohnRubanSingh, пожалуйста, помогите мне. Мы можем присоединиться к слабине.
Шивам Шарма
0

Установка этих двух свойств была достаточной, чтобы заставить его работать для меня и не подвергать угрозе безопасности:

 WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setDomStorageEnabled(true);
GreuM
источник
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();
    }

Если вы хотите добавить дополнительный дополнительный уровень безопасности, вы можете попробовать использовать закрепление сертификата . ИМХО это не обязательно для частного или внутреннего использования.

Если вы планируете опубликовать приложение в Google Play Store, вам следует избегать @Override onReceivedSslError (...) {...}. Особенно с использованием handler.proceed (). Google найдет этот фрагмент кода и обязательно отклонит ваше приложение, так как решение с handler.proceed () подавит все виды встроенных механизмов безопасности .

И то, что браузеры не жалуются на ваше https-соединение, не означает, что самому SSL-сертификату вообще доверяют!

В моем случае была нарушена цепочка сертификатов SSL . Вы можете быстро проверить такие проблемы с помощью SSL Checker или другого промежуточного звена с SSLLabs . Но, пожалуйста, не спрашивайте меня, как это может случиться. Я понятия не имею.

В любом случае, после переустановки SSL-сертификата все ошибки, касающиеся « ненадежного SSL-сертификата в WebView вообще », исчезли окончательно. Я также удалил @Override для onReceivedSslError (...) и избавился от handler.proceed () , и é voila, мое приложение не было отклонено Google Play Store (снова).

Мануэль
источник