安卓版微信Webview中两个页面互相跳转的BUG

Heero.Luo发表于8年前,已被查看3410次

都说微信是移动端的IE6,不管你们信不信,反正我信了。最近在开发过程中就遇到了一个极其容易触发的BUG。

复现这个BUG只需要两个页面「a.html」以及「b.html」,并且两个页面都有跳去另一个页面的链接:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>A</title>
</head>

<body>
<h1>I am A.</h1>
<p><a href="b.html">to B</a></p>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>B</title>
</head>

<body>
<h1>I am B.</h1>
<p><a href="a.html">to A</a></p>
</body>
</html>

先打开「a.html」,点击链接跳转到「b.html」,再点击「b.html」中的链接跳转到「a.html」。如此往复点击跳转几次,就会出现无法再次跳转的情况(会出现进度条,但是无法跳转)。

这极有可能是微信在网页历史记录方面的BUG。然而,你并不能指望微信能很快地修复它,所以只能自己寻找解决方法。经过多次的尝试,我发现这个BUG在两种情况下不会触发:

  1. 页面上没有viewport的声明;
  2. 跳转的URL上带有问号(有问号就行了,不需要带参数)。

在移动端页面上,不声明viewport肯定是不可行的,所以只能考虑方法2。虽然说可以把链接改成这样:

<p><a href="a.html?">to A</a></p>
<p><a href="b.html?">to B</a></p>

但是实际项目中的链接非常多,一个一个地改很麻烦而且容易漏掉。这种情况用Javascript的事件代理模式来处理是比较合适的:

$('body').on('click', function(e) {
	var target = e.target;
	if (isAndroid && isInWX && target.tagName === 'A' && !target.search) {
		// 只设为问号无效,所以还是得加个参数
		// 其实很想换成另一个f开头的单词
		target.search = '?fixwx';
	}
});

这样做是有副作用的:页面跳转后URL就会带上了一个参数。如果你是个洁癖,不想URL不干净,也可以调用HTML 5的历史记录接口把它干掉:

var location = window.location;
if (location.search === '?fixwx') {
	history.replaceState(
		null,
		document.title,
		location.pathname + location.hash
	);
}

最后必须提一下,这个方法并不能100%解决问题,因为有些跳转是用Javascript跳的,没有经过click事件。

评论 (5条)

发表评论

(必填)

(选填,不公开)

(选填,不公开)

(必填)