【问题标题】:How can I check from Android WebView if a page is a "404 page not found"?如果页面是“未找到 404 页面”,我如何从 Android WebView 检查?
【发布时间】:2021-03-27 15:39:20
【问题描述】:

我想从 WebView 中检查“未找到 404 页面”,如果是 404,那么我将返回 上一页。求你的帮助

编辑我想查看的网页是纯 .jpg 1.jpg 2.jpg 3.jpg 但我不知道存在多少图像。所以如果有人可以提出另一种方法,欢迎他这样做。

【问题讨论】:

  • 您可能需要查看 android-developers 组的 this thread

标签: android webview


【解决方案1】:

从 SDK 23 (Android M) 开始,您可以使用 onReceivedHttpError 方法捕获 404 和其他 HTTP 错误。只需覆盖您的WebViewClient

@Override
public void onReceivedHttpError (WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    Toast.makeText(view.getContext(), "HTTP error "+errorResponse.getStatusCode(), Toast.LENGTH_LONG).show();
}

【讨论】:

  • 请记住 This callback will be called for any resource (iframe, image, etc), not just for the main page - 来自文档
  • 我试过这个,但是当我在 API 24 设备上得到 404 时,我的代码会跳过它。
  • 你知道这是否可以用来检测失败的 AJAX 请求吗?还是只针对从主文档中获取的资源?
【解决方案2】:

我可能晚了几年,但这是我必须解决的问题,因为这些答案都不起作用。

我最终使用了 onReceivedTitle 并将标题与我试图打开的站点中的页面标题(在本例中为“找不到页面”)进行了比较。

webview.setWebChromeClient(new WebChromeClient() {
        @Override
        public void onReceivedTitle(WebView view, String title) {
            // TODO Auto-generated method stub
            super.onReceivedTitle(view, title);


            CharSequence pnotfound = "The page cannot be found";
            if (title.contains(pnotfound)) {
                pagenotfound = true;
                view.stopLoading();
                webview.loadUrl("https://www.google.com/search?hl=en&q=stackoverflow");

            }
        }

        public void onProgressChanged(WebView view, int progress) {
            activity.setProgress(progress * 1000);
        }
    });

webview.setWebViewClient(new WebViewClient() {
        @Override
        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {

            Toast.makeText(activity, "Oh no! " + description,
                    Toast.LENGTH_SHORT).show();

        }

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);

            return true;
        }

        public void onPageFinished(WebView view, String url) {
            if (dialog.isShowing()) {
                dialog.dismiss();

            }
        }
    });

“pnotfound”会因站点而异。但通常一个站点使用相同的“找不到页面”,因此您可以使用站点上的标题。 如果您使用多个网站,您可能需要添加 else if for。

希望它对某人有所帮助。

【讨论】:

  • 感谢您提供此技巧。似乎没有一种直接(非 hacky)的方法来找出 404。
  • 这是一个很好的答案!!这绝对对我有用,并且节省了我用头撞墙的时间!!!谢谢分享!!!
  • 虽然聪明,但这不是一个好的解决方案。您可能只想检查 Android 的库存“网页不可用”以检测网络错误,但请注意,这会因任何其他语言而中断(更不用说操作系统将来可能会更改此标题)。
【解决方案3】:

我会尝试检测 404 页面的加载。您可以通过在WebViewClient 类中实现shouldOverrideUrlLoading 方法来做到这一点。

mGenericWebClient = new GenericWebClient();
mWebView.setWebViewClient(mGenericWebClient);

public class GenericWebClient extends WebViewClient {
    public boolean shouldOverrideUrlLoading(WebView view, String url)
    {
        if (url=="your404page.html") {
            view.goBack();
            return true;
        }
        return false;
   }
}

您也可以检查onReceivedError事件是否出现,当404错误发生时。

【讨论】:

  • 如果 404 页面不受我控制怎么办?访问一些匿名网站返回 404?
【解决方案4】:

您不需要完全加载页面来检查它是否会导致 404 错误:

private int getRange() {
    try {
        HttpURLConnection.setFollowRedirects(false);
        int Count = 1;
        URL testURL;
        while (true) {
            testURL = new URL(
                    (myURL + "/" + Integer.toString(Count++) + ".jpg"));
            HttpURLConnection con = (HttpURLConnection) testURL
                    .openConnection();
            con.setRequestMethod("HEAD");
            if (con.getResponseCode() == 404) {
                return Count - 2;
            }
            Log.e("RESPONCE", Integer.toString(con.getResponseCode()));
        }
    } catch (Exception e) {

    }
    return 1;
}

【讨论】:

  • 这与 WebView 无关,这是最初的问题。
  • 我不同意这个答案的反对意见。在发布此答案三年后,Android WebView 仍然没有提供任何检查当前加载页面的 HTTP 状态的方法。这为开发人员留下了外部解决方案,例如 @weakwire 的贡献。必须理解,建议的解决方案将用作“预验证”步骤,然后(如果)将 URL 加载委托给WebView。不过,我选择不评论代码质量。
  • 2017年4月好像还是这样吧? @dbm
【解决方案5】:
@Override
public void onPageFinished(WebView view, String url) {
   super.onPageFinished(view, url);
   String pageTitle = myWebView.getTitle();
   String[] separated = pageTitle.split("-");
   if(separated[0].equals("404")) {
       Log.i(TAG, "detect page not found error 404");
   }
   else {
       findViewById(R.id.progress1).setVisibility(View.GONE);
   }
}

【讨论】:

    【解决方案6】:

    我可能迟到了这个帖子,但这是我解决它的方法。因为,我的应用程序处理动态 URL 和多语言网站,上述解决方案都不适合我。 onReceivedHttpError 可以为任何资源(iframe、图像等)调用,而不仅仅是主页,所以我决定为 mainPage 添加一个检查。

    这就是我的做法:

     @Override
    public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
        if (request !=null && request.getUrl() !=null)
            if (request.getUrl().toString().equals(dynamicURL) && errorResponse.getStatusCode()==404) {
                //Handle the error
            }
    }
    

    这里,dynamicURL 是加载到活动的webview 中的主 url。通过添加此检查,我现在只会在主页抛出 404 时出错。

    PS:如果您的页面的 url 不返回 404,这可能对您不起作用。

    【讨论】:

      【解决方案7】:

      如果您是在 webview 中加载的页面的网站管理员,您可以将页面标题设置为“404”。然后在加载页面后,您可以使用 getTitle() 方法获取页面标题。然后,如果它包含 404 或者它与您的页面标题不同,您可以做您想做的事情。

      例子:

      myView.setWebViewClient(new WebViewClient(){
          @Override  
              public void onPageFinished(WebView view, String url) {  
                 String pageTitle = myView.getTitle();
                 Toast.makeText(getBaseContext(), pageTitle, Toast.LENGTH_SHORT).show();
              }
      });
      

      【讨论】:

      • 返回的标题可能包含也可能不是 404。不同的平台和/或设备可能会返回不同的标题名称。
      • 我已经编辑了我的答案,好像用户是页面的站长一样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      相关资源
      最近更新 更多