在 Android WebView 中获取 HTTP 状态码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11889020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:05:46  来源:igfitidea点击:

Get HTTP Status Code in Android WebView

androidhttpandroid-webview

提问by Victor Escobar

I'm developing an Android app that loads a website in a WebView, but sometimes the website returns HTTP code 500.

我正在开发一个在 WebView 中加载网站的 Android 应用程序,但有时该网站会返回 HTTP 代码 500。

My question is: is there any way to get the HTTP status code from a WebView with a listener or with another class??

我的问题是:有没有办法从带有侦听器或其他类的 WebView 获取 HTTP 状态代码?

I tried to implement an WebViewClient, but I couldn't get the HTTP status code which WebView received.

我试图实现一个 WebViewClient,但我无法获得 WebView 收到的 HTTP 状态代码。

回答by Jeffrey Blattman

It's not possible (as of the time i'm writing this). The docs for onReceiveError()are ambiguous at best, but it you look at this issue,

这是不可能的(截至我写这篇文章的时候)。的文档onReceiveError()充其量是模棱两可的,但你看看这个问题,

http://code.google.com/p/android/issues/detail?id=968

http://code.google.com/p/android/issues/detail?id=968

It's clear that HTTP status codes won't be reported through that mechanism. How it's possible that the developers wrote WebViewwith no way to retrieve the HTTP status code really blows my mind.

很明显,HTTP 状态代码不会通过该机制报告。开发人员如何编写WebView无法检索 HTTP 状态代码的方法真的让我大吃一惊。

回答by Alexander Ponomarev

You can load content with ajax and then just put it into the webview with loadDataWithBaseURL.

您可以使用 ajax 加载内容,然后使用 loadDataWithBaseURL 将其放入 webview。

Create a web page like this

创建一个这样的网页

<script type="text/javascript">
    function loadWithAjax() {
        var httpRequest = new XMLHttpRequest();
        var path = 'PATH';
        var host = 'HOST';
        var url = 'URL';

        httpRequest.onreadystatechange = function(){
            if (httpRequest.readyState === 4) { 
                if (httpRequest.status === 200) {
                    browserObject.onAjaxSuccess(host, url, httpRequest.responseText);
                } else {
                    browserObject.onAjaxError(host, url, httpRequest.status);
                }
            }
        };

        httpRequest.open('GET', path, true);
        httpRequest.send(null);
    }
</script>
<body onload="loadWithAjax()">

browserObjectis java object injected into javascript.

browserObject是注入到 javascript 中的 java 对象。

addJavascriptInterface(this, "browserObject");

And load it into webView. You should replace path/url with your values.

并将其加载到 webView 中。您应该用您的值替换路径/网址。

ajaxHtml = IOUtils.toString(getContext().getAssets().open("web/ajax.html"));
            ajaxHtml = ajaxHtml.replace("PATH", path);
            ajaxHtml = ajaxHtml.replace("URL", url);
            ajaxHtml = ajaxHtml.replace("HOST", host);

loadDataWithBaseURL(host, ajaxHtmlFinal, "text/html", null, null);

Then handle onAjaxSuccess/onAjaxError like this:

然后像这样处理 onAjaxSuccess/onAjaxError:

    public void onAjaxSuccess(final String host, final String url, final String html)
    {
        ((Activity) getContext()).runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                loadDataWithBaseURL(url, html, "text/html", null, null);
            }
        });
    }

    public void onAjaxError(final String host, final String url, final int errorCode)
    {

    }

Now you can handle http errors.

现在您可以处理 http 错误了。

回答by Jose Gómez

It looks as though this is possible via a new callback in the Android M API (https://code.google.com/p/android/issues/detail?id=82069#c7).

看起来这可以通过 Android M API ( https://code.google.com/p/android/issues/detail?id=82069#c7) 中的新回调实现。

void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)

void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)

Unfortunately, this will most likely not available in pre-Android M devices.

不幸的是,这很可能在 Android M 之前的设备中不可用。

回答by gman413

Actually it's not too bad to check HTTP status to see if content is available to load into a webview. Assumed: You've already set your webview and you have the string for your target URL then...

实际上,检查 HTTP 状态以查看内容是否可以加载到 web 视图中还不错。假设:你已经设置了你的 webview 并且你有你的目标 URL 的字符串然后......

    AsyncTask<Void, Void, Void> checkURL = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            pd = new ProgressDialog(WebActivity.this, R.style.DickeysPDTheme);
            pd.setTitle("");
            pd.setMessage("Loading...");
            pd.setCancelable(false);
            pd.setIndeterminate(true);

            pd.show();
        }
        @Override
        protected Void doInBackground(Void... arg0) {
            // TODO Auto-generated method stub
            int iHTTPStatus;

            // Making HTTP request
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpGet httpRequest = new HttpGet(sTargetURL);

                HttpResponse httpResponse = httpClient.execute(httpRequest);
                iHTTPStatus = httpResponse.getStatusLine().getStatusCode();
                if( iHTTPStatus != 200) {
                    // Serve a local page instead...
                    wv.loadUrl("file:///android_asset/index.html");
                }
                else {

                    wv.loadUrl(sTargetURL);     // Status = 200 so we can loard our desired URL
                }

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "UNSUPPORTED ENCODING EXCEPTION", Toast.LENGTH_LONG).show();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "CLIENT PROTOCOL EXCEPTION", Toast.LENGTH_LONG).show();

            } catch (IOException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "I/O EXCEPTION", Toast.LENGTH_LONG).show();

            }  catch (Exception e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "GENERIC EXCEPTION", Toast.LENGTH_LONG).show();

            }

            return null;
        }


    };

    checkURL.execute((Void[])null);

Elsewhere, in WebViewClient, dismiss the progress dialog

在其他地方,在 WebViewClient 中,关闭进度对话框

@Override  
    public void onPageFinished(WebView view, String url)  
    {
        // Do necessary things onPageFinished
        if (pd!=null) {
            pd.dismiss();
        }

    }       

回答by Ken Shiro

At this time you cannot get normal HTTPresponse code.

此时您无法获得正常的HTTP响应代码。

But as solution, if is possible to you to modify webapp server side, to use following:

但是作为解决方案,如果您可以修改 webapp 服务器端,请使用以下内容:

On the server create some JavaScriptfunction, let's say, riseHttpError.

在服务器上创建一些JavaScript函数,比方说,riseHttpError.

On android side use JavaScriptinterface and when you need to tell android to handle http error, just call Android.riseHttpError()on server.

在 android 端使用JavaScript接口,当您需要告诉 android 处理 http 错误时,只需Android.riseHttpError()在服务器上调用。

Android will handles this function and you will be able to do required actions on android side.

Android 将处理此功能,您将能够在 android 端执行所需的操作。

In my solution were required to get errors. You can send any code you want. :)

在我的解决方案中需要得到错误。您可以发送任何您想要的代码。:)

Of course, this is just another variation how to do it. So, probably there is others, much better solutions.

当然,这只是如何做的另一种变体。所以,可能还有其他更好的解决方案。

But if you can modify server side, I think, this will be better to do double request using URLHandler.

但是,如果您可以修改服务器端,我认为,使用URLHandler.

回答by Mike

I don't think it is possible to get status code in easy way(if it's at all possible) from webView.

我认为不可能从 webView 以简单的方式(如果可能的话)获取状态代码。

My idea is to use onReceivedError() method from WebViewClient(as you said) with defined errors in WebViewClient (full list of errors is available here: http://developer.android.com/reference/android/webkit/WebViewClient.html) and assume that for instance 504 status code is equals to WebViewClient.ERROR_TIMEOUT etc.

我的想法是使用 WebViewClient 中的 onReceivedError() 方法(如您所说),并在 WebViewClient 中定义错误(完整的错误列表可在此处获得:http: //developer.android.com/reference/android/webkit/WebViewClient.html)并假设例如 504 状态代码等于 WebViewClient.ERROR_TIMEOUT 等。

回答by Jaroslav

You can override method onReceivedHttpError and there you can see the status code:

您可以覆盖方法 onReceivedHttpError 并在那里您可以看到状态代码:

@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    super.onReceivedHttpError(view, request, errorResponse);
    int statusCode = errorResponse.getStatusCode();
    // TODO: dou your logic..
}

回答by Harsh Mittal

You should use this after the on Page finished

您应该在页面完成后使用它

@Override 
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error){
    //Your code to do
    Toast.makeText(
        getActivity(), 
        "Your Internet Connection May not be active Or " + error,
        Toast.LENGTH_LONG
    ).show();
}