即带有文件输入的javascript表单提交
Posted
技术标签:
【中文标题】即带有文件输入的javascript表单提交【英文标题】:ie javascript form submit with file input 【发布时间】:2012-03-12 21:01:44 【问题描述】:我有一个带有自定义文件上传字段的 html 表单。我的意思是我已经使用 css 将实际的文件字段移动到页面的边界之外,我有一个自定义输入字段和按钮,并且我有一个 jquery click 事件附加到该自定义按钮来触发文件输入对话框。 在每个浏览器中一切正常。
但我需要通过 javascript 提交表单。我在某个地方发现 IE 将我使用 javascript 的操作记录为对文件输入字段的恶意操作,并在我调用 document.formName.submit()
时阻止我的访问并显示错误 "access denied"
。
有没有办法解决这个问题,因为我试图寻找解决方案已经完全发疯了。我真的不想使用默认的文件输入字段,因为每个浏览器都会以不同的方式呈现它并弄乱我的设计..
代码:
<form name="thisForm" onsubmit="return false;" enctype="multipart/form-data" method="post" action="index.cfm/somepage">
<input type="file" class="hidden" name="hidden" id="hidden" />
<input type="text" name="shown" id="shown" />
<button id="button">browse..</button>
<input type="submit" id="submitForm" />
</form>
<script>
$('button').click(function()
$('#shown').val($('#hidden').val());
);
$('submitForm').click(function()
validateForm();
);
function validateForm()
//regular expression validation against all other input fields in the form
//not the file input field
validateVAT();
function validateVAT()
//connect to external service to check VAT
submitForm();
function submitForm()
document.thisForm.submit();
</script>
更新: 我只是尝试在通过 ajax 提交表单之前先上传文件,但这也给了我访问被拒绝的错误。>_>
【问题讨论】:
你能发布你的文件字段操作代码吗?我以前从未在 IE 中看到过该错误! 这篇文章讨论了文件输入的样式选项和可能有帮助的 JS 解决方案:quirksmode.org/dom/inputfile.html adrianlynch:代码(基本形式)已经存在:第一次点击事件。我只将隐藏字段的值传输到可见输入字段。二极管:那行不通,它基本上做我所做的,从隐藏字段中获取值.. 您可以使用“this.submit”,因为指针焦点在提交按钮上 怎么回事?我没有提到我在表单标签上有onsobmit="return false"
,并且在点击处理程序和实际的 form.submit 调用之间有一个验证函数。但我认为这是不言自明的......
【参考方案1】:
我遇到了同样的问题,我通过在 Firefox 中使用带有样式的 <label>
标记和一个轻微的解决方法解决了它。
http://jsfiddle.net/djibouti33/uP7A9/
目标:
-
允许用户使用标准 html 文件输入控件上传文件
隐藏标准 html 文件输入控件并应用自己的样式
用户选择要上传的文件后,自动提交表单
浏览器:
Firefox、Chrome、IE8/9、Safari IE7 不起作用,但如果您将其添加到下面详述的解决方法中,它可能会起作用。初步解决方案:
-
通过将文件输入置于屏幕外来隐藏它。重要的是不要显示:无,因为某些浏览器不喜欢这样。
向页面添加另一个样式元素(链接、按钮)。
监听对该元素的点击,然后以编程方式向文件输入发送点击以触发本机“文件资源管理器”
监听文件输入的 onchange 事件(在用户选择文件后发生)
提交表格
问题:
-
IE:如果您以编程方式向文件输入发送点击以激活它 (2),以编程方式提交表单 (5) 将引发安全错误
变通解决方案:
-
同上
通过设置样式来利用标签标签中内置的辅助功能(单击标签将激活它的关联控件)
标签标签而不是链接/按钮
监听文件输入的 onchange 事件
提交表格
由于某种原因,Mozilla 浏览器不会通过单击文件的标签来激活文件输入。
对于 Mozilla,监听标签上的点击并向文件输入发送点击事件以激活它。
希望这会有所帮助!查看 jsfiddle 以了解有关用于使其正常工作的 html/js/css 的详细信息。
【讨论】:
天才。在 ie8 中对我很有用 :) 巧妙的解决方案!这也适用于移动浏览器(经过测试的 android 4、BlackBerry PlayBook 2 和 ios 6),无需在解决方法步骤 #6 中手动触发点击事件。 多么棒的工作。谢谢你。完全让我开心。 太棒了!一个优雅而简单的解决方案。 完美解决方案!哇!这应该是公认的答案。顺便说一句:Firefox 现在可以工作了,至少在 24 版上。没有尝试任何其他版本。【参考方案2】:经过 2 天的疯狂试错,我自己找到了答案。我希望我能帮助别人。..
我从我的 Coldfusion 页面中删除了隐藏的文件输入字段,并将其替换为 iframe 标记。该 iframe 标记链接到另一个coldfusion 页面,其中包含另一个带有已删除文件输入字段的表单。 现在,当我使用 javascript 单击仍然隐藏在视图中的文件输入字段时,它仍然会毫无障碍地提供浏览文件对话框。但是当我使用 javascript 通过 iframe 提交表单时,奇迹般地,它在 iframe 中提交了表单,从而可以在您喜欢的某些服务器端脚本中上传文件。
iframe 代码:
<form id="formFileUpload" class="formFileUpload" name="formFileUpload" method="post" action="../actions/act_upload_file.cfm" autocomplete="off" enctype="multipart/form-data">
<input type="file" class="buttonFileHidden" id="inputFile" name="partnersLogo" />
</form>
iframe 本身:
<iframe src="admin/dsp_file_upload.cfm" id="ifu" name="ifu" class="buttonFileHidden">
</iframe>
javascript 点击并提交:
ifu.document.formFileUpload.partnersLogo.click();
ifu.document.formFileUpload.submit();
【讨论】:
【参考方案3】:如果您像我一样,不想使用 iframe,并且您不太热衷于上述标签解决方案,您可以将原始按钮放置在不透明度为的样式按钮上方0.
使用上面的示例,您仍然可以:
<input type="file" class="hidden" name="hidden" id="hidden" />
<input type="button" name="shown" id="shown" value="Add File" />
但是.hidden
会这样定义:
.hidden
position: absolute;
left: -150px;
opacity: 0;
filter: alpha(opacity=0);
配置:将不透明度设置为 0.5(或 =50)以查看透明元素并调整左侧位置。
可以说和上面的答案一样 hacky,但是一个引导友好的解决方案,就我而言,是唯一一个有效的解决方案。
【讨论】:
【参考方案4】:我找到了一个奇怪的解决方案来解决这个问题。
它想到了js点击线程。如果它超出此线程,则不再存在安全问题。
我选择使用 window.setTimeout。请参阅下面的示例:
<script type="text/javascript">
$(function ()
$("#<%= this.fuDoc.ClientID %>").bind('change', uploadFile);
$("#<%= this.btnUpload.ClientID %>").click(chooseFile);
);
function chooseFile()
$("#<%= this.fuDoc.ClientID %>").click();
function uploadFile()
var fu = $("#<%= this.fuDoc.ClientID %>");
if (fu.val() != "")
window.setTimeout(function ()
<%= this.ClientScript.GetPostBackEventReference(this.btnUpload, "") %>;
, 100);
</script>
<asp:FileUpload ID="fuDoc" runat="server" style="display: none;" />
<asp:Button runat="server" ID="btnUpload" Text="upload" OnClick="btnUpload_Click" />
<asp:Label ID="lbltext" Text="" runat="server" />`
那么,没有更多的访问被拒绝!
【讨论】:
欢迎来到 ***!这是我见过的最好的书面第一个答案之一。尽量避免诸如“希望它可以提供帮助”之类的东西。谢谢:-)【参考方案5】:这是一个旧帖子,但问题仍然存在。这可能不起作用,因为 jQuery 会默默地失败。我遇到了这个问题,想知道为什么我的隐藏表单不会提交并且文件会被上传。我从使用 jQuery 开始,但后来我变成了香草。它仍然不起作用,但看起来好像在我的 .click()
函数中引发了异常。
跑步
try
document.getElementById('formid').submit();
catch (e)
alert(e);
表明我们确实抛出了一个错误,并且快速研究表明这是因为 IE 不支持对文件输入的模拟点击。这意味着当要发布表单时,IE 会拒绝发布表单
请原谅粗体字,但我知道很多人会看到文字而不阅读它
【讨论】:
奇怪的是,我发现如果你循环 try / catch,第三次提交将通过(带有文件数据!),但我还必须考虑不显眼的验证错误,如果file 是必需的,因为 DOM 会坚持认为控件没有价值。【参考方案6】:你试过了吗
$('button').click(function()
$('form[name=thisForm]').submit()
);
【讨论】:
【参考方案7】:您需要将onsumbit='return false;'
更改为onsubmit='return validateForm()'
。
如果表单通过验证检查,则让validateForm()
返回 true,否则返回 false。
onsubmit='return false'
阻止表单通过document.thisForm.submit();
提交以及当用户单击提交按钮时。
【讨论】:
错误。这是 msie 中的一个安全问题,当浏览器检测到任何 javascript 干预文件输入字段时,它会拒绝提交表单。与我如何提交表单无关。为了澄清,我不想使用return ValidateForm();
,因为我必须通过外部服务调用检查增值税,这必须在不同的功能中发生,并且必须在返回任何东西之前完成..
嗯...在安全问题上我会相信你的话,但是为什么不在输入字段更改时验证增值税,那么你就不必通过外部service onsubmit(您可能也在验证服务器端,所以它同样安全)【参考方案8】:
我在 j query.form.js 中评论了这些行,然后一切对我来说都很好。不要问我原因,即使我没有解决方案,但它肯定有效。
if (io.contentWindow.document.execCommand)
try // #214
io.contentWindow.document.execCommand('Stop');
catch(ignore)
【讨论】:
当然,在相同的上下文中遇到相同的安全问题,它不起作用。以上是关于即带有文件输入的javascript表单提交的主要内容,如果未能解决你的问题,请参考以下文章
提交表单时,不会保存对 Rails 输入标记的 javascript 更改