Javascript被拦截的“Ctrl + O”不打开我的文件对话框 [英] Javascript Intercepted "Ctrl+O" Does Not Open My File Dialog

查看:122
本文介绍了Javascript被拦截的“Ctrl + O”不打开我的文件对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



现在,我从此答案获取代码,截取 Ctrl + O 按键和打开我的文件对话框,所以我有这个:

  $(window).bind('keydown',function(e)
{
if(e.ctrlKey || e.metaKey)
{
switch(String.fromCharCode(e.which).toLowerCase())
{
case's':
e.preventDefault();
//对于这个问题无关
return false;
case'o':
e.preventDefault();
document.getElementById(choose-file-button)。click();
return false;
}
}
return true ;
});

如您所见,当我截获 Ctrl + O 我点击我的#选择文件按钮按钮,调用 document.getElementById(browse-button); 在其 onclick 处理程序中。我在这个点击处理程序中放了一个断点,当我按 Ctrl + O 它到达这个断点。但是,文件对话框永远不会出现。



通过调试,我发现如果我把一个 alert(...) code>之后的#选择文件按钮单击()行,然后警报显示正常页面打开文件对话框显示(不是我的文件对话框)。如果我没有这个警报,那根本就没有显示。



这是一个bug吗?如何修复它,并通过截取的 Ctrl + O 显示我的文件对话框?



编辑:我刚刚在Chrome中测试,它的工作原理完美。但是,它仍然在Firefox中不起作用。

解决方案

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



编辑:正如所怀疑的,大多数浏览器会跟踪事件是否基于事件类型是否受信任,以及是由用户创建还是以编程方式生成。有关详细信息,请此答案。正如你所看到的,由于键盘事件不在列表中,它们永远不会被信任。



测试JSFiddle

 < form action =#方法= POST > 
< div>
< input type =fileid =myfilename =myfile/> < a href =#id =mylinkaccesskey =o>点击我< / a>
< / div>
< / form>

$(#mylink)点击(function(){
$(#myfile)click();
});

$(window).bind('keydown',function(e){
if(e.ctrlKey || e.metaKey){
switch(String.fromCharCode e.white).toLowerCase()){
case'o':
e.preventDefault();
console.log(1a);

$(#myfile)。click();
// alert(hello);

console.log(1b);
return false;
}
}
return true;
});

我认为这里只有两个选项,它们都是解决方法,而不是解决方案。 p>


  • 一个是使用链接触发文件上传对话框,并要求人们使用ALT + SHIFT + O而不是CTRL + O(因为我添加了一个 accesskey 属性

  • 另一个替代方法是使用一种新的HTML5 JavaScript API来实现拖放文件上传



附录:我还尝试在Firefox中使用纯JavaScript抓取一个点击事件,并检查是否使用 isTrusted 属性信任。对于链接的点击,它返回 true 。但是,尝试存储和重新使用其他地方的事件不起作用,因为在您获得引用的时候它已被分派。另外,令人惊讶的是,创建一个新事件并尝试设置 isTrusted = true 由于它是只读的,因此不起作用。


I have an <input type="file" id="browse-button"/> file-browser input in my HTML.

I have another button with ID choose-file-button that, when clicked, calls document.getElementById("browse-button").click();. When this button is clicked, it correctly clicks #browse-button and the file dialog opens.

Now, I took code from this answer to intercept a Ctrl+O keypress and open my file dialog, so I have this:

$(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;
});

As you can see, when I intercept Ctrl+O I click on my #choose-file-button button, which calls document.getElementById("browse-button"); in its onclick handler. I have put a breakpoint in this click handler, and when I press Ctrl+O it does arrive at this breakpoint. However, the file dialog never shows up.

Through debugging, I found out that if I put an alert(...); after the #choose-file-button click() line, then the alert shows up and the normal page "Open File" dialog shows up (not my file dialog). If I do not have this alert, however, nothing shows up at all.

Is this a bug? How can I fix it and make my file dialog show up via the intercepted Ctrl+O?

Edit: I just tested in Chrome, and it works perfectly. However, it still does not work in Firefox.

解决方案

There's some browser security magic going on here. When using timeouts or intervals or any other methods I try, the code carries on as normal but the browser simply refuses to open a file upload dialog. This is probably deliberate, to stop malicious JS from trying to grab users' files without consent. However, if you bind to a click event on a link, it works perfectly using jQuery or regular JS.

Edit: As suspected, most browsers keep track of whether an event is trusted or not based on the type of event and whether it was created by the user or generated programmatically. Se this answer for the full details. As you can see, since keyboard events aren't in the list, they can never be trusted.

Test 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;
});

I think there are only two options here, and they're both workarounds, not solutions.

  • One is to use a link to trigger the file upload dialog, and ask people to use ALT+SHIFT+O instead of CTRL+O (because I added an accesskey attribute to the link in the example).
  • The other alternative is to use one of the new HTML5 JavaScript APIs for drag-drop file uploading.

Addendum: I also tried using pure JavaScript in Firefox to grab a click event and check to see if it's trusted using the isTrusted property. For the clicks on the link, it returned true. However, attempting to store and re-use the event elsewhere doesn't work, because it's already been dispatched by the time you get a reference to it. Also, unsurprisingly, creating a new event and attempting to set isTrusted = true doesn't work either since it's read-only.

这篇关于Javascript被拦截的“Ctrl + O”不打开我的文件对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆