Javascript Intercepted”;Ctrl+O”;不打开“我的文件”对话框

Javascript Intercepted "Ctrl+O" Does Not Open My File Dialog

本文关键字:我的 文件 我的文件 对话框 Intercepted Ctrl+O Javascript      更新时间:2023-09-26

我的HTML中有一个<input type="file" id="browse-button"/>文件浏览器输入。

我有另一个ID为choose-file-button的按钮,单击后会调用document.getElementById("browse-button").click();。单击此按钮后,它将正确地单击#browse-button,并打开文件对话框。

现在,我从这个答案中提取代码来拦截Ctrl+O键并打开我的文件对话框,所以我有了这个:

$(window).bind('keydown', function(e)
{
    if (e.ctrlKey || e.metaKey)
    {
        switch (String.fromCharCode(e.which).toLowerCase())
        {
            case 's':
                e.preventDefault();
                // doesn't matter for this question
                return false;
            case 'o':
                e.preventDefault();
                document.getElementById("choose-file-button").click();
                return false;
        }
    }
    return true;
});

正如您所看到的,当我截取Ctrl+O时,我会单击#choose-file-button按钮,该按钮在其onclick处理程序中调用document.getElementById("browse-button");。我在这个点击处理程序中放置了一个断点,当我按下Ctrl+O时,它确实到达了这个断点。但是,文件对话框永远不会显示。

通过调试,我发现如果我在#choose-file-button click()行后面放了一个alert(...);,那么警报就会出现正常页面"打开文件"对话框就会出现(而不是我的文件对话框)。然而,如果我没有这个警报,什么也不会出现。

这是个虫子吗?我如何修复它并通过截获的Ctrl+O显示我的文件对话框?

编辑:我刚刚在Chrome中进行了测试,它运行得很好。然而,它在Firefox中仍然不起作用。

这里有一些浏览器安全魔法。当使用超时或间隔或我尝试的任何其他方法时,代码会正常运行,但浏览器只是拒绝打开文件上传对话框。这可能是故意的,目的是阻止恶意JS试图在未经同意的情况下抓取用户的文件。然而,如果您绑定到链接上的点击事件,那么它可以使用jQuery或常规JS完美地工作。

编辑:正如所怀疑的那样,大多数浏览器都会根据事件的类型以及它是由用户创建还是以编程方式生成来跟踪事件是否可信。请参阅此答案以了解全部细节。正如您所看到的,由于键盘事件不在列表中,因此它们永远不会被信任。

测试JSFiddle

<form action="#" method="post">
    <div>
        <input type="file" id="myfile" name="myfile" /> <a href="#" id="mylink" accesskey="o">Click me</a>
    </div>
</form>
$("#mylink").click(function () {
    $("#myfile").click();
});
$(window).bind('keydown', function (e) {
    if (e.ctrlKey || e.metaKey) {
        switch (String.fromCharCode(e.which).toLowerCase()) {
            case 'o':
                e.preventDefault();
                console.log("1a");
                $("#myfile").click();
                //alert("hello");
                console.log("1b");
                return false;
        }
    }
    return true;
});

我认为这里只有两种选择,它们都是变通办法,而不是解决方案。

  • 一种是使用链接来触发文件上传对话框,并要求人们使用ALT+SHIFT+O而不是CTRL+O(因为我在示例中为链接添加了accesskey属性)
  • 另一种选择是使用一个新的HTML5 JavaScript API进行拖放文件上传

附录:我还尝试在Firefox中使用纯JavaScript获取点击事件,并使用isTrusted属性检查它是否可信。对于链接上的单击,它返回true。然而,尝试在其他地方存储和重用该事件是不可行的,因为当你获得对它的引用时,它已经被调度了。此外,毫不奇怪,创建一个新事件并尝试设置isTrusted = true也不可行,因为它是只读的。

Browser将许多Ctrl+快捷键映射到自己的命令,例如Ctrl+O来打开文件(在firefox中)。

同时,当您试图覆盖javascript中的此类快捷方式时,浏览器的行为会有所不同。有些浏览器允许你这样做,有些则不允许,有时默认的浏览器操作可能会与javascript的操作一起弹出。

这是另一个讨论这个话题的话题。

也许你能做的最好的事情就是选择不同的快捷方式。

您可以尝试使用Mousetrap库。它覆盖了关键点捕获造成的大多数问题。官方网站和完整参考:

https://craig.is/killing/mice

祝好运

你不可能在所有浏览器中都这样做,就我而言,只有IE允许这样做。我想这是由于安全问题,所以程序员无法自动在HTML file元素上设置文件名(未经客户端许可)。

查看此链接了解更多详细信息:

在JavaScript中,我可以制作一个";点击";事件以编程方式激发文件输入元素?

加载时显示输入文件对话框?