即javascript表单提交文件输入

时间:2012-02-22 14:09:12

标签: javascript jquery html forms

我有一个html表单,带有自定义文件上传字段。并且我的意思是我已经用css将实际文件字段移动到页面的边界之外,我有一个自定义输入字段和按钮,并且我有一个附加到该自定义按钮的jquery click事件来触发文件输入对话框。 在每个浏览器中一切正常。

但我需要通过javascript提交表单。我找到了某个地方,当我调用"access denied"时,IE会记住我使用javascript作为对文件输入字段的恶意操纵,并阻止我访问时出现错误document.formName.submit()

有没有解决方法,因为我试图寻找解决方案已经完全疯了。我真的不想使用默认的文件输入字段,因为每个浏览器都会以不同的方式呈现它并弄乱我的设计..

代码:

<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,但这也给了我拒绝访问错误..&gt; _&gt;

8 个答案:

答案 0 :(得分:64)

我遇到了同样的问题,我在Firefox中使用带有轻微解决方法的样式<label>标记解决了这个问题。

http://jsfiddle.net/djibouti33/uP7A9/

目标:

  1. 允许用户使用标准html文件输入控件上传文件
  2. 隐藏标准html文件输入控件并应用自己的样式
  3. 用户选择要上传的文件后,自动提交表单
  4. 浏览器:

    • Firefox,Chrome,IE8 / 9,Safari
    • IE7无法正常工作,但如果您将其添加到下面详述的解决方法中,可能会有效。

    初始解决方案:

    1. 通过将文件输出放在屏幕外来隐藏文件输入。重要的是不要显示:none,因为有些浏览器不喜欢这个。
    2. 向页面添加另一个样式元素(链接,按钮)。
    3. 听取对该元素的点击,然后以编程方式发送一个单击到文件输入以触发本机“文件浏览器”
    4. 侦听文件输入的onchange事件(在用户选择文件后发生)
    5. 提交表格
    6. 问题:

      1. IE:如果您以编程方式将单击发送到文件输入以激活它(2),则以编程方式提交表单(5)将引发安全性错误
      2. 变通方法解决方案:

        1. 与上述相同
        2. 通过样式化利用标签标签内置的辅助功能(点击标签将激活它的相关控件) 标签标签而不是链接/按钮
        3. 侦听文件输入的onchange事件
        4. 提交表格
        5. 由于某些原因,Mozilla浏览器不会通过单击其标签来激活文件输入。
        6. 对于Mozilla,请听标签上的点击,然后将单击事件发送到文件输入以激活它。
        7. 希望这有帮助!查看jsfiddle,了解用于使其全部工作的html / js / css的详细信息。

答案 1 :(得分:11)

我自己找到了答案,经过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点击&amp;提交:

ifu.document.formFileUpload.partnersLogo.click();
ifu.document.formFileUpload.submit();

答案 2 :(得分:5)

如果您像我一样,并且您不想使用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,但是一个引导友好的解决方案,在我的情况下,唯一有效的解决方案。

答案 3 :(得分:2)

我找到了解决这个问题的奇怪解决方案。

它考虑了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" />`

然后,不再拒绝访问!

答案 4 :(得分:2)

这是一个老帖子,但问题仍然存在。这可能不起作用,因为jQuery默默地失败了。我遇到了这个问题,并想知道为什么我的隐藏表单不会提交并且文件上传。我开始使用jQuery,但后来我去了香草。它仍然没有用,但看起来好像在我的.click()函数中抛出异常。

运行

try {
    document.getElementById('formid').submit();
} catch (e) {
    alert(e);
}

表明我们确实犯了一个错误,快速研究表明这是因为 IE不支持模拟输入上的模拟点击。这意味着当表单发布时,IE将拒绝发布表单

请原谅大胆的上限,但我知道很多人会看到文字,而不是阅读

答案 5 :(得分:-1)

你试过吗

  $('button').click(function(){
        $('form[name=thisForm]').submit()
    });

答案 6 :(得分:-1)

您需要将onsumbit='return false;'更改为onsubmit='return validateForm()'

如果表单通过验证检查,则validateForm()返回true,否则返回false。

onsubmit='return false'阻止表单通过document.thisForm.submit();以及用户点击提交按钮时提交。

答案 7 :(得分:-1)

我在j query.form.js中注释了这些行,然后每件事都适合我。不要问我原因,即使我没有解决方案,但它确实有效。

        if (io.contentWindow.document.execCommand) {
          try { // #214
               io.contentWindow.document.execCommand('Stop');
         } catch(ignore) {}
      }