Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Failed to submit form when no file selected #180

Closed
alexius opened this Issue · 17 comments

6 participants

@alexius

Version 2.87 worked fine until upgraded to 3.02.

Getting error "file exceeds the defined ini size" when submitting a form without file selected.
If force to use iframe than everything works fine, but thats not a solution.

I analyzed the all version until 3.02 and find out than changes in 2.90 made this error.

just commented:

//  causing errors
//  var fileAPI = feature.fileapi && feature.formdata;
var fileAPI = false;

for temporary solution

@malsup
Owner

Which browser?

@alexius

last version of chrome and firefox

@alexius

well, I've analyzed a problem a little more.
I'm using Zend Framework and zend_form for uploading files.
Zend_Validate_File_Upload throws ini error because there is no <input type="file" name="file"> submitted that is present in form object witch validates the post request.

Maybe this is more Zend Framework problem than that of jquery.form but it is much more simplier to change jquery.form than dig in Zend Framework jungle.

:)

Maybe you can offer some solution instead of

// var fileAPI = feature.fileapi && feature.formdata;
var fileAPI = false;
@OndraM

I'm also experiencing this issue with the new version of Form plugin (3.03), with previously used 2.82 it was OK.

When no file is selected, the plugin now don't send the form as multipart/form-data even when specified in <form>, and the $_FILES is empty in PHP, thus causing mentioned error in Zend Framework.

IMO the behavior of plugin is now not correct.

@malsup
Owner

v3.08 is the latest. Can you test with that?

@OndraM

Yep, tried just now, the issue is still present there.

@OndraM

Are you able to reproduce the issue? If no, I may prepare some demo to demonstrate it - if you'd like to.

@malsup
Owner

Fixed in 3.09.

@malsup malsup closed this
@OndraM

I'm sorry, but the new version makes no difference with this issue.

I created a simple gist demonstrating the different behavior on ajax form and standard form with file upload: https://gist.github.com/2401014

And here is screenshot of current result: http://dl.dropbox.com/u/15226372/screenshots/jquery-form-180.png

@malsup
Owner

It appears that an ajax post doesn't send the same headers for an empty file input. If you have a pull request to fix this I'd be happy to apply it.

@OndraM

I made a deeper investigation of the issue, and found this as some kind of limitation (or maybe feature?) of XHR level 2.

  • This problem only appear when browser is capable of fileAPI
  • When files are appended to the FormData object (formdata.append(a[i].name, a[i].value);), the value is empty string.
  • According to .append() specs: set its type to "text" if value is a string.
  • So the item is treated as a string, which causes that Content-Type: application/octet-stream is not added to the POST request as in the standard form, making the $_FILES empty in PHP.

I tried to use empty BlobBuilder object to pass the append a BLOB object, but this actually causes an upload of an empty file. Also the third parameter of FormData.append (filename), which may allow to pass "empty" file name, seems to be unimplemented in browsers yet (https://bugzilla.mozilla.org/show_bug.cgi?id=736324, https://bugzilla.mozilla.org/show_bug.cgi?id=690659...).

From my point of view, it appears as a glitch in the specification, which the browsers implements. Or maybe in the PHP, which is then unable to recognize that empty file field was send. The only workarounds I see is fallback to the iframe method (fileUploadIframe), or hack the validator in Zend From...

@OndraM

I've created the fallback handling and reverted the previous change in 3.09. For me it works fine now, but I'm not creating a pull request, since this may not be the cleanest solution (at least until the behavior is changed in ZF). You may of course use the commit, if you want to.

For the record, I've also created ZF issue: http://framework.zend.com/issues/browse/ZF-12159

@ybart

Unfortunately, this broke a form of mine :broken_heart:

When I don't upload using AJAX, the file inputs are not sent to the server. I think that the ajaxform behavior should match the browser one.

@zgmnkv

It seems that this issue is still not fully fixed.
Wrong behavior is in the line 862 (there's also a comment related to this issue on line 861)
a.push({ name: n, value: '', type: el.type });
So, jquery.form tries to send empty string when no file is selected, while native behavior is to send empty file.
As an example here's what jquery.form sends if no file was selected (from Google Chrome):

------WebKitFormBoundary5dOYNbbxTmBGyyVP
Content-Disposition: form-data; name="photo"


------WebKitFormBoundary5dOYNbbxTmBGyyVP

And what Google Chrome sends without jquery.form:

------WebKitFormBoundaryWNFAubVszG9aWqrI
Content-Disposition: form-data; name="photo"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryWNFAubVszG9aWqrI

So, the fix seems to be easy: set the value to empty file instead of empty string in lint 862.
But the problem is that javascript does not allow you to create a File instance, it could be only created when user selects a file with <input type="file">.

Instead of File object we can use Blob object, as File extends Blob with some extra fields.
See details at http://www.w3.org/TR/FileAPI/#dfn-file

I tried to simply set value to new Blob() in line 862. But behavior is still not like native:

------WebKitFormBoundaryq97MUrwUErZRon9b
Content-Disposition: form-data; name="photo"; filename="blob"
Content-Type: application/octet-stream


------WebKitFormBoundaryq97MUrwUErZRon9b

Browser sends filename="blob" when Blob object is passed to FormData.
Find details here: http://www.w3.org/TR/XMLHttpRequest/#interface-formdata

I also tried to send empty string as filename parameter to formData.append but filename in request was still 'blob'. Maybe this is browser-specific.

As a result, I still can't make ajax request be exactly the same as native browser request. But I think sending new Blob() is better than sending empty string, as it has proper Content-Type in request.

On server-side I have Java Servlet with Spring Framework, and it works wrong with empty string sended if no file selected. It works fine with new Blob(), even if filename is 'blob' instead of ''. I have a manual check if file size equals 0 and I don't process file in this case, so it doesn't matter what filename was sended.

@malsup
Owner

To work around this issue you can use the iframe: true option.

@tsantos84

Just to let you know that I'm using jQuery Form 3.20 and I'm getting the same error as zagumennikov has described. I've setted the option iframe to true and worked to me, but I think this is not the best solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.