【问题标题】:How do you configure Firefox to allow Javascript to intercept a value pasted from the clipboard?如何配置 Firefox 以允许 Javascript 拦截从剪贴板粘贴的值?
【发布时间】:2012-05-25 06:49:51
【问题描述】:

当用户从剪贴板粘贴时,我需要过滤掉某些字符。 (我实际上并不想修改剪贴板中的内容。)我已经在 IE 中使用它。 叹息...

tl;dr: user.js 中的 capability.policy 项目使其进入 prefs.js 但未生效。

仅供参考,我可以合理地让所有用户安装 user.js。但是我们都没有对我们机器的管理员访问权限,所以这就是我在配置方面所能做的所有事情。

感谢您的帮助!

注意:

  1. 出于这个问题的目的,我不想“绕过”访问剪贴板 --
    例如,我不想对 DOM 元素的值进行操作之后出现粘贴
  2. 我不想要一个需要 framework/library 的解决方案(如 jQuery、Dojo、Prototype、YUI,...)

遵循的步骤

  1. 通过转到 URL about:support => 配置文件目录 => 打开包含文件夹 确定我的 profile 文件夹的位置

  2. 尝试通过使用以下行创建 user.jsenable clipboard in Firefox: user_pref("just.mike", "测试 user.js 是否有效。"); user_pref("capability.policy.policynames", "allowclipboard"); user_pref("capability.policy.allowclipboard.sites", "https://my-site.com"); user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess"); user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess"); 注意:https://my-site.com 不是真正的网站。

  3. 事实证明,capability.policy 项目在使用 about:config 时是可见的——由于 Bugzilla Bug 284673 - about:config hides "capability.policy" preferences。但是,我确实认为这些 user.js 项“有效”并且该文件位于正确的文件夹中,因为之后:
    • about:config 显示了 just.mike 条目
    • prefs.js 包含所有新行但顺序不同——按字母顺序排列: user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess"); user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess"); user_pref("capability.policy.allowclipboard.sites", "https://my-site.com"); user_pref("capability.policy.policynames", "allowclipboard"); ... user_pref("just.mike", "测试 user.js 是否有效。");
    (仅供参考,我还在任何地方尝试了Zallowclipboard,以便policynames 行由于字母顺序排在第一位,但这也不起作用。)

  4. onpaste 事件之后尝试read the clipboard in Firefox,并具有以下内容: var 剪贴板 = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard); 如果(!剪贴板){ throw new Error('内部错误 -- 无法创建剪贴板对象'); } var transferable = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); 如果(!可转让){ throw new Error('内部错误——无法创建可转移对象'); } transferable.addDataFlavor("text/unicode"); clipboard.getData(可转移,clipboard.kGlobalClipboard); var clipboard_data = new Object(); var clipboard_length = new Object(); transferable.getTransferData("text/unicode", clipboard_data, clipboard_length); var 剪贴板文本 = ''; 如果(!!剪贴板数据){ var clipboard_nsISupportsString = clipboard_data.value.QueryInterface(Components.interfaces.nsISupportsString); clipboard_text = clipboard_nsISupportsString.data.substring(0, clipboard_length.value / 2); } 返回(剪贴板文本);
  5. 代码在 first 行失败,在 Firebug 控制台中返回此错误: 获取属性 XPCComponents.classes 的权限被拒绝 注意:我实际上是在真实的 URL 上运行它,它确实会显示在错误消息中——我只是在这里将它更改为一个虚拟名称。

  6. 我还看到some 其他示例,其中在第一行使用createInstance 而不是getService,但first 行仍然生成相同的错误文本: var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard); // ...


环境 (这是我无法控制的)

  • 没有管理员访问计算机的权限
  • Windows Vista
  • Mozilla 火狐 10

参考文献

【问题讨论】:

  • 您说您不想“绕过”访问剪贴板。为什么?在我看来,唯一的解决方案是在 textarea/input 上检测 control-v,然后从那里编辑文本。那有什么问题?表现?除非你真的对文本感到疯狂,否则我怀疑你会看到任何闪烁或任何东西。
  • 我用谷歌搜索了一下这个问题,发现一些代码显示了nsIClipboardnsISupportsStringnsITransferable 之后的初始化,也许这可能会影响。 developer.mozilla.org/en/Using_the_Clipboard
  • 您的问题到底是什么?这听起来可能很奇怪,但也许你正在用你认为可以解决的问题来克服你的问题。暴露what you want as the final result可以给我们更多的空间来打开新的解决方案。

标签: javascript firefox windows-vista configuration-files onpaste


【解决方案1】:

简而言之,我认为不可能按照自己的意愿去做自己想做的事。 Mozilla(和大多数现代浏览器)出于安全原因限制剪贴板访问。您似乎很容易绕过 IE 中的这个限制,这不是一个令人欣慰的想法。

话虽如此,插件与网页有不同的限制,您可以通过编写一个(或者甚至利用 Flash)来绕过这个限制。但是,即使使用插件,我怀疑您阻止某人将某些内容粘贴到 Web 表单(或其他任何内容)的唯一方法是抢先清理他们的剪贴板。

如果您只想阻止某些字符串被输入到文本框中,最好的办法是监视文本框本身的事件。

不过,如果我没看错的话,听起来您想强迫用户在表单中输入(并且只输入)某些内容,而我想不出一种简单的方法。几个重要的选项:

  1. 将文本框设置为readonly,并弹出虚拟键盘强制用户“输入” 使用他们的鼠标框。 (你必须自己用 HTML 和 JavaScript,或者在某个地方找到合适的解决方案。)
  2. 监控oninput事件;如果文本框变化得更快,那么一个人可以 合理地期望输入,拒绝更改。

这些都不是很漂亮,但是如果您想使用开放网络技术创建解决方案,那么您必须接受您正在构建的系统的限制,以及它的好处

【讨论】:

    【解决方案2】:

    Grubby 但跨浏览器的方式是将当前输入的值与之前的 onchange 事件进行比较。

    如果它的长度增加或值差异太大(不仅减少而且有很多新字符) - 可能是从剪贴板粘贴了一些东西。 像这样的:

    $('input, textarea').change(function(){
      var prev = $(this).data('prev-val'), 
          current = $(this).val();
      if (is_big_changes(prev,current)) {
        $(this).val(my_filter_func(current));
      }
      if (!prev) {
         $(this).data('prev-val', current);
      } 
    })
    

    (这只是概念证明,所以我使用 jQuery 来避免大量编码)

    is_big_changes 和 my_filter_func 在哪里——您需要实现的函数。

    警告 使用这种方法可能会出现很多邪恶的错误,我知道,它看起来非常丑陋。我的交易是提出建议。

    【讨论】:

    • 感谢 Nayjest 的尝试,但请参阅问题顶部的“编辑注释”说明。
    【解决方案3】:

    我们可以说,您需要检测剪贴板粘贴吗?当您知道那里以前的内容时,您就知道发生了什么变化。

    那么为什么不简单地挂钩 onchange 呢?不粘贴内容开头和结尾的所有相同字符。如果您想将此与简单的击键区分开来,请同时听 keydown/keypress,然后您就知道哪些更改来自“其他地方”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多