【发布时间】:2021-03-27 15:39:20
【问题描述】:
我想从 WebView 中检查“未找到 404 页面”,如果是 404,那么我将返回 上一页。求你的帮助
编辑我想查看的网页是纯 .jpg 1.jpg 2.jpg 3.jpg 但我不知道存在多少图像。所以如果有人可以提出另一种方法,欢迎他这样做。
【问题讨论】:
-
您可能需要查看 android-developers 组的 this thread。
我想从 WebView 中检查“未找到 404 页面”,如果是 404,那么我将返回 上一页。求你的帮助
编辑我想查看的网页是纯 .jpg 1.jpg 2.jpg 3.jpg 但我不知道存在多少图像。所以如果有人可以提出另一种方法,欢迎他这样做。
【问题讨论】:
从 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 - 来自文档
我可能晚了几年,但这是我必须解决的问题,因为这些答案都不起作用。
我最终使用了 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。
希望它对某人有所帮助。
【讨论】:
我会尝试检测 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 错误:
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 仍然没有提供任何检查当前加载页面的 HTTP 状态的方法。这为开发人员留下了外部解决方案,例如 @weakwire 的贡献。必须理解,建议的解决方案将用作“预验证”步骤,然后(如果)将 URL 加载委托给WebView。不过,我选择不评论代码质量。
@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);
}
}
【讨论】:
我可能迟到了这个帖子,但这是我解决它的方法。因为,我的应用程序处理动态 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,这可能对您不起作用。
【讨论】:
如果您是在 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();
}
});
【讨论】: