在卸载页面之前拦截新URL

时间:2019-03-16 19:10:33

标签: javascript html5

问题:我是一个用户,需要使用一个Web应用程序,该应用程序的锚点列表为href="javascript://"。当我单击其中任何一个时,脚本将执行一些操作(此处无关),最后导航到新页面。

我的问题是我希望将此新页面加载到新的选项卡上,而不是让当前的选项卡导航到其他页面。由于链接指向无处,因此我无法右键单击它并在新选项卡中将其打开。

(我想要这样做的原因是因为我必须经常来回移动,所以如果可以将每个项目加载到不同的选项卡中,则可以节省大量时间)

问题是否可以在窗口卸载之前拦截要加载的新URL?还是没有浏览器扩展就不可能做到,即使使用控制台执行脚本?

解决方案的想法:如果window.onbeforeunload可以捕获要分配给window.location的新URL,我可以window.open(newURL,'_blank')然后阻止默认的导航行为到新网址。


  • 更新:将window.openwindow.history.pushSatereplaceStatewindow.location.assignreplace更改为{{1 }}没什么区别,因此都没有被调用。最有可能使用null。是否可以收听对window.location的任何呼叫?还是可以在window.location中添加一些内容,以使locationlocation = newURL不会重定向,而只是使用此location.href = newURL打开一个新标签页?

  • 第二次更新:我通过反转预期的行为解决了我的问题。我无法在新标签页中打开每个项目,而是在导航到新页面之前,使在新标签页中打开的项目的每次单击都使用先前的URL。也就是说,我向每个项目添加了一个newURL,并且在单击该项目时会运行以下命令:eventListener。我仍然想知道是否有可能拦截新的URL,因为这仍然是最好的解决方案

1 个答案:

答案 0 :(得分:1)

由于已(显然)将问题隔离到location=location.href=的实例,因此您应该能够从全局名称空间中窃取所有这些问题。 您可以先定义

var location = {};  

所有违规赋值语句现在都应该变得无害。

如果这意味着您继承的代码的其他部分失败,或者您只是想要一个更彻底的解决方案,则可以将整个客户端代码库(自定义location对象除外)包装在一个函数中,该函数会在任何时候做出响应你那个对象改变了。一个有用的响应是用atarget="_blank"或类似的东西创建一个href=" ${location.href} || ${location} || #标签。


或者,您可以使自定义位置对象不可变(未经测试):

const location = {};
Object.defineProperty( location, "href", {
  value: "whatever",
  writable: false,
  enumerable: true,
  configurable: true
});

现在,任何尝试分配给locationlocation.href的尝试都将引发错误,例如[Invalid_const_assignment][1]。如果您的包装函数使用try / catch来执行其余的源代码,则可以捕获这些错误以使应用程序始终运行,查看分配尝试将您发送到的URL,并希望对此做一些有用的事情。 / p>


最后,如果原始开发者显式使用window.location而不是location,那将是一条更大的鱼,但是您有两种选择。

一种方法是找到前一种情况的所有实例并将其替换为后者,以使上述建议适用。实现此目的的一种方法是使用Sublime Text中的“在文件夹中查找”菜单选项(使用Sublime打开src文件夹后。)显然,在进行此类操作之前,您需要进行可靠的备份(例如git commit)鲁global的全球变化。

另一种方法是尝试破解窗口对象。这已经超出鲁re性,任何受尊敬的浏览器都应该防止这种情况,但是浏览器不知道的包装功能(如上所述)可以模拟这种情况。

也就是说,如果您应用的源代码的执行上下文是带有其自己的“本地” window对象的包装函数,则与window.somePropertywindow.someMethod的任何交互都应找到您的自定义版本,它可以充当网守,为某些属性(例如location)添加自定义处理,同时将所有其他分配和方法调用转发到“真实”窗口对象。

此转发可能是最困难的部分,具体取决于应用程序试图与window进行哪些特定的交互。如果没有什么可担心的交互,您可以根据具体情况抢先处理每种类型,但是我们已经超出了我的知识范围,无法解决这种情况的动态解决方案(也许使用代理对象? )是我什至不打算进一步讨论的内容。

相反,这里someone else's (related?) thoughts是使用jQuery的,但是如果您需要走这么远的话,编写一个小的浏览器扩展程序以根据需要自动复制和删除其他选项卡可能是一个更简单的解决方法。