即带有文件输入的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 中使用带有样式的 &lt;label&gt; 标记和一个轻微的解决方法解决了它。

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 更改

如何使用ajax提交带有输入文件的表单

表单标签中的按钮不会提交或响应 Javascript/Jquery

JavaScript 提交带有锚标记的表单(链接)

javascript 一键提交多个表单