触发点击input=文件上的asynchronousajax完成()
我有一些数据和上传的表单。 只有成功接收和处理数据,才能启动上传。 为了做到这一点,我做了一个阿贾克斯电话,我在哪里
- 发送数据,
- 检查其结果,
- 触发一个click()来打开一个文件对话框。
click()的最后一件事情不起作用,因为似乎asynchronous调用会打开一个上传窗口 。 它只适用于async: false
。
我找不到任何文档和这个网站,并想知道那里有什么问题,以及如何使它保持调用asynchronous?
例:
$.ajax({ type: "POST", url: "/Save", data: jsonText, dataType: "json", //async: false [1] }).done(function (msg) { $("#upload").click(); }); //$("#upload").click(); [2]
演示: http : //jsfiddle.net/c2v00uxn/
注意:
- 如果我取消注释[1]或[2],它确实有效(文件对话框按预期显示)。
- 用触发器replaceclick()('click')不起作用
- 用live()/ on()replaceclick()并没有帮助
- file upload控制是可见的每个例子(所以这不是因为隐藏的控制)
- 超时设置阿贾克斯没有帮助。
UPDATE
一般来说,如何做一个“点击”并不是关于如何在一个asynchronous的ajax调用之后点击(到目前为止,只适用于非asynchronous调用)。
由于浏览器中的w3cbuild议的安全function,现在不可能从asynchronousajaxcallback中打开文件popup窗口。
在文件input元素的激活行为中,它首先检查algorithm是否允许显示popup窗口 ,如果不是,则不做任何其他操作就中止下一步。 来自w3c.org
如果满足以下任一条件,algorithm可以显示一个popup窗口:
- algorithm正在运行的任务当前正在处理其单击事件被信任的激活行为(可信事件:由用户代理生成的事件,可以是用户交互的结果,也可以是直接由DOM,受到用户代理程序的信任,这些权限不通过
DocumentEvent.createEvent("Event")
方法由脚本生成,使用Event.initEvent()
方法修改或通过EventTarget.dispatchEvent()
方法,可信事件的isTrusted属性的值为true,不可信事件的isTrusted属性值为false,否则为http://www.w3.org/TR/2012/WD-DOM-Level-3-Events -20120614 /#可信事件 。) -
algorithm正在运行的任务当前正在为其types位于以下列表中的受信任事件运行事件侦听器:
- 更改
- 点击
- DBLCLICK
- 鼠标松开
- 重启
- 提交
- algorithm运行的任务是通过允许显示popup窗口的algorithm排队,并且这种algorithm的链在用户代理定义的时间范围内开始 。
w3c.org
在你的代码中,click事件不是由用户触发的,而是由ajax完成callback触发的。 在这里,浏览器声明事件不能被信任打开一个popup窗口。 在某些浏览器中,如果将事件声明为可信,则可以看到isTrusted
属性设置为true。 https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
注意
不同的浏览器使用不同的方法来捕捉脚本激活的脚本和真正的用户之间的区别。
在这种情况下你可以做的是禁用文件inputbutton(或整个表单),并在完成Ajax后启用。 这样用户不会点击上传button,直到ajax请求完成。 到目前为止,还没有其他方法可以一次点击,因为打开popup窗口也有一个时间限制。 当我检查铬时间是1000毫秒。 用户操作后1000ms,窗口不会被打开。
我有一个解决scheme,现在工作。 这是一个黑客攻击,所以它可能不会在不久的将来,因为它规避了上述Tkay提到的安全function。
我引入了一个超时,等待ajax请求返回我想要检查的数据,然后启动文件浏览器对话框。
customFileUploadButton.addEventListener('click', function(e) { var returnValueToCheck; //Value we want to check against //reference to vanilla JS ajax function that takes callback ajax(function(ajaxData) { returnValueToCheck = ajaxData; }); setTimeout(function() { if (returnValueToCheck !== undefined) { //dummy check for example file.click(); } else { console.log("Criteria not fulfilled"); } }, 1000);//timer should be larger than AJAX timeout });
说实话,我有点不确定为什么这个工作除了显然通过浏览器特定的testing通常禁止这种行为。 因此,我认为这是一个黑客。
我的例子是香草JS,但应该很容易创build一个jQuery版本。 完整的例子见这个JSFiddle 。
(这是我第一次参与贡献,所以请对潜在的错误和疏忽进行评论)
JQuery本身说,触发器不能用于file upload和锚点等元素。 (来源 – https://learn.jquery.com/events/triggering-event-handlers/ )
.trigger()函数不能用来模拟本机浏览器事件,例如单击文件input框或定位标记。 这是因为,没有事件处理程序使用与这些事件相对应的jQuery事件系统附加。
所以在这种情况下,您可能需要使用以下JavaScript函数手动创build事件。
- document.createEvent
- event.initMouseEvent
- element.dispatchEvent
上述function的示例代码+定义可以在Mozilla的开发人员站点中find
https://developer.mozilla.org/samples/domref/dispatchEvent.html
也许,这会帮助你。
$(function () { $('#demo').click(function () { $.ajax({ type: "POST", url: "/echo/json/", data: "jsonText", dataType: "json", }).done(function (msg) { $("#demo").addClass("test"); }).fail(function(jqXHR, textStatus, errorThrown){ alert(textStatus); }); if($("#demo").hasClass("test")){ $("#upload").click(); } }); });