如何在浏览器中禁用或删除粘贴上下文菜单项

How to disable or remove the paste context menu item in browsers

本文关键字:删除 上下文 菜单项 浏览器      更新时间:2023-09-26

我有一个信用卡网站,我需要在上面创建一个帐户。显然,他们希望他们的帐户持有人在所有网站上使用相同的密码,这样当下一个大帐户漏洞发生时,他们必须支付尽可能多的钱。为此,他们决定禁止在网站上的密码字段上使用剪贴板,以阻止账户持有人使用密码管理器。

对于Firefox和IE11用户来说,浏览器上下文菜单中的"粘贴"菜单项是灰色的,这真的很奇怪。对于Chrome用户来说,粘贴和粘贴为纯文本上下文菜单项完全缺失。

我一直在查看他们网站上的标记和JavaScript,发现他们在键盘和鼠标事件中添加了事件侦听器,以阻止剪贴板访问密码字段,但真正令人困惑的是,当用户右键单击浏览器中的输入时,他们是如何更改上下文菜单的内容的。密码字段只是一个具有密码类型的输入元素。

<input readonly tabindex="51" maxlength="20" style="height: 22px; width: 200px;" class="gwt-PasswordTextBox gwt-PasswordTextBox-readonly gwt-Focus" type="password">

我对如何阻止Ctrl-V或通过JavaScript拦截鼠标对字段的粘贴访问并不感兴趣。我知道怎么做。我的问题是他们如何更改浏览器上下文菜单的内容。请参阅我的答案中的概念证明,了解为什么这与另一个问题不同。

实际上不应该是调整上下文菜单的问题(除非这是您的设计规范),而是,您只需要禁用粘贴功能。

这个例子展示了如何"杀死"一个给定元素的粘贴。记住,它仍然会在上下文菜单上显示粘贴,但这种行为在第一个密码字段中不起作用:

window.addEventListener("DOMContentLoaded", function(){
  var p1 = document.getElementById("p1");
  p1.addEventListener("paste", function(evt){
      evt.preventDefault();
      evt.stopPropagation();
  });
});
<input type="password" id="p1" placeholder="Paste won't work in me.">
<input type="password" id="p2" placeholder="Paste will work in me.">

现在,如果您确实需要调整上下文菜单,最好的跨浏览器方法是处理元素上的contextmenu事件,并阻止该事件的默认行为(就像我在代码段中阻止粘贴行为一样),但随后显示一个以前准备好的、但只是隐藏的对话框。有关更多详细信息,请参阅:http://www.sitepoint.com/building-custom-right-click-context-menu-javascript/

另请参阅:https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu有关contextmenu事件的更多信息。

我和另一个同事一起看了更多。输入中的只读属性是缺少上下文菜单项的原因。通过添加只读属性,我可以让username字段显示相同的精简上下文菜单

显然,他们使用JavaScript事件侦听器拦截击键,并将它们传递给这个只读字段,这样你就可以输入密码了。

这里有一个非常简化的概念证明:

<!DOCTYPE html>
<html>
<head>
	<title>Using a Read-only Field as an Input to Overly Control User Experience</title>
	<script>
		function passAlongKeys(e) {
			//debugger;
			//TODO handle backspace, delete key, current insertion point etc.
			e.currentTarget.value =  e.currentTarget.value + e.char;
		}
	</script>
</head>
<body>
	<p>Plain text:<input id="text" type=="text" ></p>
	<p>Plain password: <input id="password" type=="password" ></p>
	<p>Readonly text: <input id="textro" readonly ></p>
	<p>Readonly password:<input type=password id="passwordro" readonly ></p>
	<p>Readonly text with JS:<input id="textrojs" type=text onkeydown="passAlongKeys(event)" readonly ></p>
	<p>Readonly password with JS:<input id="passwordrojs" type=password onkeydown="passAlongKeys(event)" readonly ></p>
</body>
</html>