Android WebView không tải 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    
}

Khi tôi cố gắng tải một URL trong WebBView, nó chỉ hiển thị một màn hình trống. Nếu tôi tải Google.com hoặc yahoo.com thì nó hoạt động tốt.


1
nó đang hoạt động tôi đã kiểm tra ngay bây giờ. kiểm tra lại nếu không hoạt động sau đó thêm mã này với mã của bạn webView.getSettings (). setUseWideViewPort (true); webView.getSettings (). setLoadWithOverviewMode (true);
ilango j

Câu trả lời:


155

Vui lòng truy cập liên kết này:

Thêm phương pháp ghi đè này vào triển khai WebViewClient của bạn. Bạn sẽ cần phải biên dịch nó với Android SDK 2.2 (API cấp 8) trở lên. Phương pháp này xuất hiện trong SDK công khai kể từ 2.2 (API cấp 8) nhưng chúng tôi đã thử nghiệm nó trên các thiết bị chạy 2.1, 1.6 và 1.5 và nó cũng hoạt động trên các thiết bị đó (vì vậy rõ ràng là hành vi đã tồn tại ở đó).

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

Điều này sẽ giúp bạn.


3
Mục cuối cùng trong cuộc thảo luận đã hoạt động tốt. Cảm ơn rất nhiều.
Bill Lahti

54
Cảnh báo bảo mật : Lưu ý rằng làm như vậy hoàn toàn đánh bại mục đích của việc có SSL ngay từ đầu.
vào

8
Xin đừng làm điều này. Nó không an toàn và không được phép trong Cửa hàng Play.
Antimony

33
Google hiện đang gửi email cho bất kỳ ai triển khai giải pháp ở trên: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

3
Bất kỳ ai biết cách giải quyết Cảnh báo bảo mật của google, nếu có, xin vui lòng cho tôi biết vì tôi cũng đang đối mặt với vấn đề này.
Pratik Tank

49

Theo câu trả lời đúng của fargth, sau đây là một mẫu mã nhỏ có thể hữu ích.

Đầu tiên, tạo một lớp mở rộng WebViewClient và lớp này được đặt để bỏ qua lỗi 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
            }

}

Sau đó, với đối tượng chế độ xem web của bạn (được khởi tạo trong phương thức OnCreate ()), hãy đặt ứng dụng khách chế độ xem web của nó thành một phiên bản của lớp ghi đè:

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );

2
điều này đưa ra cảnh báo bảo mật của google: triển khai không an toàn trình xử lý WebViewClient.onReceiveSslError. bạn có biết làm thế nào để giải quyết điều này?
Pratik Tank

2
Google Đánh dấu Ứng dụng là Chưa được xác nhận trên playstore làm thế nào có thể làm điều đó mà không có ssl?
Ajay Pandya

Không sử dụng phương thức Super- super.onReceiveSslError (view, handler, error);
Atul Bhardwaj

41

Để xử lý đúng cách xác thực chứng chỉ SSL và tránh từ chối ứng dụng từ Google theo Chính sách bảo mật mới, hãy thay đổi mã của bạn để gọi SslErrorHandler.proceed () bất cứ khi nào chứng chỉ do máy chủ cung cấp đáp ứng mong đợi của bạn và gọi SslErrorHandler.cancel () nếu không.

Ví dụ: tôi thêm hộp thoại cảnh báo để làm cho người dùng đã xác nhận và dường như Google không còn hiển thị cảnh báo nữa.

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

Sau khi thay đổi này, nó sẽ không hiển thị cảnh báo.


điều gì sẽ xảy ra nếu tôi xóa khối onReceiveSslError khỏi quá trình triển khai?
Vivek Sinha,

1
@VivekSinha nó sẽ gọi handler.cancel (); theo mặc định.
Anant Shah,

1
nhưng Google vẫn từ chối ứng dụng của tôi với lý do tương tự. Tại sao?
Vivek Sinha,

@VivekSinha đã tìm thấy giải pháp nào liên quan đến việc khởi chạy ứng dụng trong cửa hàng Play không?
Kesha

2
Tôi đã triển khai lệnh gọi lại onReceiveSslError như được đề xuất. Ứng dụng đã được xuất bản thành công sau đó.
Vivek Sinha

11

Xóa mã bên dưới nó sẽ hoạt động

 super.onReceivedSslError(view, handler, error);

Tuyệt vời, nó đã làm việc cho tôi. Bạn có thể vui lòng giải thích cách nó hoạt động không?
Arth Tilva

3
@ArthTilva từ tài liệu google: "hành vi mặc định là hủy tải". Bằng cách gọi super, bạn đang gọi hành vi mặc định đó trước khi nó có thể tiếp cận phần còn lại của phương thức. developer.android.com/reference/android/webkit/…
Josh Laird

11

ghi đè onReceiveSslError và xóa

super.onReceiveSslError (xem, xử lý, lỗi)

Và để giải quyết vấn đề bảo mật của Google:

setDomStorageEnabled (true);

Mã đầy đủ là:

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

Cảm ơn người đàn ông rất nhiều. Loại bỏ super.onReceiveSslError (chế độ xem, trình xử lý, lỗi) đã làm việc với tôi.
Däñish Shärmà

7

Sao chép và dán dòng mã của bạn, anh bạn, nó sẽ hoạt động tin tưởng tôi :) Tôi đang nghĩ, bạn gặp lỗi ssl. İ Nếu bạn sử dụng ghi đè phương thức onReceiveSslError và loại bỏ phương thức super it. Chỉ cần viết handler.proceed (), lỗi sẽ được giải quyết.

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

Cảm ơn. Call handler.proceed () in onReceivedSslErrorsave my day
Tam Huynh

2
Nếu bạn làm điều này (bây giờ là tháng 7 năm 2019), google play sẽ từ chối đơn đăng ký của bạn.
Alp Altunel

İ có quá nhiều ứng dụng trên google play, không có ứng dụng nào vẫn bị từ chối.
ozanurkan

1
sẽ từ chối tháng 1 năm 2020 trên từ
John Ruban Singh

6

Để xử lý các url SSL, phương thức onReceiveSslError () từ lớp WebViewClient, Đây là một ví dụ:

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

        });

Bạn có thể kiểm tra ví dụ đầy đủ của tôi tại đây: https://github.com/Jorgesys/Android-WebView-Logging

nhập mô tả hình ảnh ở đây


6

Để giải quyết vấn đề bảo mật của Google, hãy làm như sau:

Các dòng lên đầu:

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

Mã:

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
Tôi mới sử dụng Android. Tôi nên đặt cái này ở đâu? :)
Gediminas

5

Tôi đã làm theo các câu trả lời ở trên nhưng có vẻ như nó vẫn không hoạt động đối với tôi, mã dưới đây đã thực hiện một mẹo cho tôi khi tích hợp các đường gom thanh toán thường là các yêu cầu 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();
        }
    }
}

Đoạn mã trên đang thực hiện yêu cầu đăng trong webview và chuyển hướng đến cổng thanh toán.

Thiết lập settings.setDomStorageEnabled(true);đã làm một thủ thuật cho tôi Hy vọng điều này sẽ giúp.


2
Giải pháp này HOÀN TOÀN vô hiệu hóa tính năng xác thực chứng chỉ, khiến bạn dễ bị tấn công bởi kẻ trung gian. Đây là điều bạn không bao giờ nên làm, ĐẶC BIỆT đối với các cổng thanh toán.
Dirbaio

Đối với tôi ban đầu, chế độ xem web không tải nội dung mà chỉ là hình nền của trang. Sau khi tôi vừa thêm webview.getSettings.setDomStorageEnabled(true);nó đã hoạt động một cách kỳ diệu. Có thể trang web đang sử dụng một số loại API HTML 5, vì vậy việc kích hoạt DomStorage phù hợp với tôi.
Ishant Sagar

handler.proceed () bỏ qua SSL
John Ruban Singh

Encodingutil.getbyte là gì
Akash kumar

2

Cách tiếp cận được đề xuất sẽ là

1. Không gọi phương thức super (Xóa super call khỏi phương thức bị ghi đè)

2.Google khuyên bạn nên gọi phương thức SslErrorHandler.cancel () nếu có bất kỳ lỗi nào xảy ra

3. Hộp thoại Không nhắc để lộ lỗi SSL

Giải pháp tốt nhất là gì ?? Xóa phương thức ghi đè này

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

}

Bạn đang yêu cầu một giải pháp hoặc đề xuất một giải pháp?
Dharman

Tôi thấy phương pháp này
John Ruban Singh

@JohnRubanSingh Xin chào John, tôi đang tải một tệp JS từ các phần tử và sau khi tệp được tải bằng onPageFi xong, tôi đang gọi một hàm bên trong JS. Vì vậy, ghi đè onReceiveSslError () là cần thiết khi tôi đang sử dụng webview.setWebViewClient (mới ....)?
Shivam Sharma

Mã này từ chối APK của tôi. Ngay cả từ 9 tháng, mã này không gây ra từ chối nhưng đột nhiên bị từ chối. R8 bây giờ. switch (error.getPrimaryError ()) {case SslError.SSL_UNTRUSTED: handler.proceed (); phá vỡ; case SslError.SSL_EXPIRED: case SslError.SSL_IDMISMATCH: case SslError.SSL_NOTYETVALID: case SslError.SSL_DATE_INVALID: case SslError.SSL_INVALID: default: handler.cancel (); phá vỡ; }
Shivam Sharma

@JohnRubanSingh làm ơn giúp tôi. Chúng ta có thể tham gia khi chậm chạp.
Shivam Sharma

0

Đặt hai thuộc tính là đủ để làm cho nó hoạt động đối với tôi và không gây ra các vấn đề bảo mật:

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

0

Sử dụng dòng này webview.getSettings (). SetDomStorageEnabled (true) trong mã java của bạn

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

0

Trong trường hợp bạn muốn sử dụng APK bên ngoài Cửa hàng Google Play, ví dụ: riêng tư, một giải pháp như sau có thể sẽ hoạt động:

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

Trong trường hợp bạn muốn thêm một lớp bảo mật tùy chọn bổ sung, bạn có thể thử sử dụng tính năng ghim chứng chỉ . IMHO điều này không cần thiết cho việc sử dụng riêng tư hoặc nội bộ khó khăn.

Nếu bạn định xuất bản ứng dụng trên Cửa hàng Google Play, thì bạn nên tránh @Override onReceiveSslError (...) {...}. Đặc biệt là sử dụng handler.proceed (). Google sẽ tìm thấy đoạn mã này và chắc chắn sẽ từ chối ứng dụng của bạn vì giải pháp với handler.proceed () sẽ ngăn chặn tất cả các loại cơ chế bảo mật tích hợp sẵn .

Và chỉ vì thực tế là các trình duyệt không phàn nàn về kết nối https của bạn, điều đó không có nghĩa là bản thân chứng chỉ SSL được tin cậy cả!

Trong trường hợp của tôi, chuỗi chứng chỉ SSL đã bị hỏng. Bạn có thể nhanh chóng kiểm tra các vấn đề như vậy với SSL Checker hoặc trung gian hơn với SSLLabs . Nhưng xin đừng hỏi tôi làm thế nào điều này có thể xảy ra. Tôi hoàn toàn không có manh mối.

Dù sao, sau khi cài đặt lại chứng chỉ SSL, tất cả các lỗi liên quan đến " chứng chỉ SSL không đáng tin cậy trong WebView là gì " cuối cùng đã biến mất. Tôi cũng đã xóa @Override cho onReceiveSslError (...) và loại bỏ handler.proceed () và rất có thể ứng dụng của tôi không bị Cửa hàng Google Play từ chối (một lần nữa).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.