Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a html form, with a custom file upload field. And by that I mean that I have moved the actual file field beyond the borders of the page with css, that I have a custom input field and button in place, and that I have a jquery click event attached to that custom button to trigger the file input dialog. It all works fine, in every browser.

But I need to submit the form through javascript. And I got somewhere that IE remembers my actions with javascript as a malicious manipulation of the file input field and blocks my access with an error "access denied" when I invoke document.formName.submit().

Is there a way around this, because I have gone completely mad by trying to search for a solution. I seriously don't want to use the default file input field, as every browsers renders it differently and messes up my design..

code:

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

UPDATE: I just tried to first upload the file, before submitting the form, through ajax, but that also gave me the acces denied error.. >_>

share|improve this question
    
Can you post your file field manipulation code? I've never seen that error from IE before! –  Adrian Lynch Feb 22 '12 at 14:17
    
This article addresses styling options for file inputs and JS solutions that may help: quirksmode.org/dom/inputfile.html –  Diodeus Feb 22 '12 at 14:18
    
adrianlynch: the code (in its basic form) is there already: the first click event. I only transfer the value of the hidden field to the visible input field. diodeus: that won't work, it basically does what I do, getting the value from the hidden field.. –  dreagan Feb 22 '12 at 14:36
    
You can use " this.submit " as the pointer focus is on the submit button –  Kunal Vashist Feb 22 '12 at 14:37
    
how so? I didn't mention I had onsobmit="return false" on the form tag and a validation function between the click handler and the actual form.submit call. But I thought that was self explanatory.. –  dreagan Feb 22 '12 at 14:41

8 Answers 8

I was having the same problem, and I solved it by using a styled <label> tag with a slight workaround in Firefox.

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

The Goals:

  1. allow user to upload a file by using standard html file input control
  2. hide standard html file input control and apply own styling
  3. after user selects file to upload, automatically submit the form

The Browsers:

  • Firefox, Chrome, IE8/9, Safari
  • IE7 didn't work, but it might if you add it to the workaround detailed below.

The Initial Solution:

  1. Hide the file input by positioning it offscreen. Important not to display:none as some browsers won't like this.
  2. Add another styled element to the page (link, button).
  3. Listen for a click on that element, then programmatically send a click to the file input to trigger the native 'file explorer'
  4. Listen for the file input's onchange event (occurs after a user chooses their file)
  5. Submit the form

The Problem:

  1. IE: if you programmatically send a click to a file input in order to activate it (2), programmatically submitting the form (5) will throw a security error

The Workaround Solution:

  1. Same as above
  2. Take advantage of the accessibility features built in to the label tag (clicking on a label will activate it's associated control) by styling a label tag instead of a link/button
  3. Listen for the file input's onchange event
  4. Submit the form
  5. For some reason Mozilla browsers won't activate a file input by clicking on it's label.
  6. For Mozilla, listen for the click on the label and send a click event to the file input to activate it.

Hope this helps! Check out the jsfiddle for details on the html/js/css used to make it all work.

share|improve this answer
1  
Genius. Worked great for me in ie8 :) –  bkempner Jan 18 '13 at 0:57
1  
GENIUS. good job. –  Rimer Mar 6 '13 at 23:49
1  
Ingenious solution! This also works on mobile browsers (tested Android 4, BlackBerry PlayBook 2, and iOS 6) without needing to manually trigger the click event in workaround step #6. –  user113215 Mar 9 '13 at 21:49
1  
What a great work around. Thanks for this. Totally made my day. –  jdavis May 20 '13 at 19:45
1  
FANTASTIC! An elegant and simple solution. –  technophobia Sep 16 '13 at 21:10
up vote 10 down vote accepted

I found the answer myself, After 2 days of crazy trial&error. I hope I can help somebody with this..

I removed the hidden file input field from my coldfusion page and replaced it by an iframe tag. That iframe tag linked to another coldfusion page, containing another form with the removed file input field. Now when I use javascript to click the file input field, which is still hidden from view, it still gives the browse file dialog without a hitch. But when I use javascript to submit the form, through the iframe, miraculously, it submits the form in the iframe, making it possible to upload the file in some serverside scripting of your preference.

iframe code:

<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 itself:

<iframe src="admin/dsp_file_upload.cfm" id="ifu" name="ifu" class="buttonFileHidden">
</iframe>

javascript click & submit:

ifu.document.formFileUpload.partnersLogo.click();
ifu.document.formFileUpload.submit();
share|improve this answer

If you're like me, and you don't want to use an iframe, and you weren't too keen on the label solution mentioned above, you can just position the original button above the styled button with an opacity of 0.

Using the example above, you would still have:

<input type="file" class="hidden" name="hidden" id="hidden" />
<input type="button" name="shown" id="shown" value="Add File" />

But .hidden would be defined like so:

.hidden {
  position: absolute;
  left: -150px;
  opacity: 0;
  filter: alpha(opacity=0);
}

Config: Set the opacity to 0.5 (or =50) to see the transparent element and tweak the left positioning.

Arguably just as hacky as the answers above, but a bootstrap-friendly solution, and in my case, the only one that worked.

share|improve this answer

I found a weird solution to solve this problem.

It thought about the js click thread. If it goes out of this thread, there no more security issues.

I chose to use window.setTimeout. see sample below:

<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" />`

then, no more acces denied!

share|improve this answer
    
Welcome to StackOverflow! This is one of the best written first answers I've seen. Just try to keep out things like "hope it can help". Thanks :-) –  FakeRainBrigand Jul 28 '13 at 21:37

This is an old post but the problem still arises. This may not be working because jQuery kindly fails silently. I was having this problem and wondering why my hidden form would not submit and the file get uploaded. I started off by using jQuery, but then I went vanilla. It still didn't work but looked as though an exception was being thrown in my .click() function.

Running

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

showed that we indeed were throwing an error, and quick research showed that this was because IE DOES NOT SUPPORT SIMULATED CLICKS ON A FILE INPUT. This means that when the form went to be posted, IE would refuse to post the form

Excuse the bold caps, but I know many people will see text and not read it

share|improve this answer
    
Strangely enough, I found that if you looped around the try / catch, the 3rd submit would go through (WITH THE FILE DATA!), but I also had to take into account unobtrusive validation errors if the file was required since the DOM would insist that the control had no value. –  Thomas S. Trias Aug 12 at 18:08

Have you tried

  $('button').click(function(){
        $('form[name=thisForm]').submit()
    });
share|improve this answer
    
stil get the "access denied" error in my console window.. –  dreagan Feb 22 '12 at 14:23

You need to change onsumbit='return false;' to onsubmit='return validateForm()'.

Then have validateForm() return true if the form passes your validation checks, or false if it does not.

The onsubmit='return false' is preventing the form from submitting via document.thisForm.submit(); as well as when the user clicks the submit button.

share|improve this answer
1  
false. It's a security issue in msie, when the browser detects any javascript meddling with a file input field, it refuses to submit the form. Has nothing to do with how I submit my form. And just to clarify, I wan't use return ValidateForm(); as I have to check the VAT in through an external service call, which has to happen in a different function and has to be completed before returning anything.. –  dreagan Feb 23 '12 at 9:35
    
Hmm... I'll take your word for it on the security issue thing, but why not validate the VAT when the input field is changed, then you wouldn't have to go via the external service onsubmit (you are presumably validating server side as well, so it would be just as secure) –  Nico Burns Feb 23 '12 at 9:47

I commented these lines in j query.form.js then every thing works fine for me. Don't ask me the reason even i don't have the solution for that but it works for sure.

        if (io.contentWindow.document.execCommand) {
          try { // #214
               io.contentWindow.document.execCommand('Stop');
         } catch(ignore) {}
      }
share|improve this answer
    
It doesn't work, for sure, with the same security problem in the same context. –  TCHdvlp Apr 22 at 8:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.