最近遇到这样一个需求:打开当前页面时,可能会带一个参数pid。页面初始化时,如果找到这个参数,会立即跳转到其对应的外部页面。当用户从外部页面返回时,可以回到当前页面,此时页面内容正常显示。我的实现是:用hash传递pid。在页面入口脚本中,如果hash中没有pid,页面会正常渲染。如果发现有pid,则不会渲染页面内容,而是通过ajax从后台获取pid对应的url。然后从location.hash中去掉pid,然后修改location.href进行跳转。在PC端的Chrome下测试正常通过,但在手机浏览器下出现问题。跳转到新页面后,按返回不会返回当前页面。在微信浏览器中,后台会直接关闭。在小米内置浏览器和夸克浏览器中,后面会回到tab初始页面,手机Chrome依然正常。我在百度上搜索,尝试了以下解决方案,但均无效:添加setTimeout延迟然后跳转,使用location.assign()代替location.href赋值,使用history.pushState手动写入当前页面的URL,然后跳转到window.onload中执行判断并延迟在window.onload中跳转并在window中执行一个模拟的点击事件。点击页面任意位置后,性能正常,新页面可以正常返回当前页面,完全满足需求预期。但是使用dispatchEvent模拟的点击事件是不会起作用的。和之前全屏API遇到的问题类似,应该是浏览器有某种策略,要求只有在用户真正点击操作时,才能进行历史操作。但奇怪的是,找了很多中文页面,都没有提到这样的问题。最后在StackOverflow上找到了一些答案(类似的问题也很少见,不过还是有答案的):HTML标准文档对history的使用有一些规范:如果满足以下任一条件,让replacementflagbeunset;否则,设置为:此Location对象的相关Document已完全加载,或在运行算法的任务中,当前正在处理点击事件的isTrusted属性为true的激活行为,或在运行算法的任务中,该算法是正在处理的点击事件的监听器,其isTrusted属性为真。大致的意思是:如果满足以下任一条件,则location对象的替换标签设置为默认,否则设置为true。(也就是说,如果不满足以下条件,对该location的任何操作都不会产生新的历史记录)location对象所在的文档已经完全加载。location的修改操作是由点击事件触发的,事件的isTrusted属性为true(即用户真正的点击操作)英文不好,找不到fullloaded的准确定义。但我推测对于遵循HTML标准的浏览器来说,只有当用户与页面交互时,页面才真正“完全加载”。在用户对页面进行操作之前,只有最后显示的页面才算有效页面,之前的所有中间跳转都应该被忽略不计入历史记录,避免后台行为死锁。我理解这个设计,这个HTML标准的定义证实了我的猜测。所以,原本设想的方案行不通,只能调整需求。最后的解决办法是加一个跳转中间页,用户点击跳转。据说Chrome没有这个问题,也就是说Chrome在这一项上没有遵循HTML标准规范?
