1

I use an HTML form to allow the user to upload files.

In order to make adding attachments more user friendly, I added client side code to allow the user to add/remove files (I basically did this as outlined in this answer).

Because I don't want to adjust too much of my server side code, I'd still like to send the form in a regular request, handle it on my server, and return an Http Response (ie: no Ajax, send request from same thread as main page and then redirect or forward the response on my Servlet).

However, the only way to submit the FormData Object is via Ajax. When I look for ways to send the FormData Object via a regular Http Request (eg: by attaching it to the form), I hear that this is not allowed because it is not safe.

Why can the FormData be submitted via XMLHttpRequest but submitting via regular Http Request (like a regular form submit) is considered not safe to the user? What's the difference? To phrase this another way: You can mess with attachments if you're submitting them via Ajax but not via a regular request. Why?

If there is a way to submit the FormData in a regular request, I would be interested to hear what it is.

Thanks.

Extra clarification (motivated by comments):

The input element on the form does not accurately represent the user's selections. I allow the user to add/remove files. I do this by creating my own Array of File Objects in the client side code. This new array of File Objects needs to be sent with the request. This is possible with Ajax (ie: by creating a FormData Object), not with regular form submit; why?

theyuv
  • 1,556
  • 4
  • 26
  • 55
  • `FormData` is used to create an object based on a `
    ` which can then be sent via AJAX. If you want to send files the non-Ajax way, just don't create a FormData object in the first place. All you have to do is add ``s to your form. Not sure where the issue is, tbh.
    –  Apr 12 '18 at 08:26
  • I am creating my own Array of `File` Objects. Please read second paragraph (including link). – theyuv Apr 12 '18 at 08:33
  • I'm aware of what you're trying to do; my suggestion is to use the array method, then to build ``s based on them and add them to a `
    `, instead of building a FormData object and sending it via AJAX.
    –  Apr 12 '18 at 09:08
  • Adding `` elements is no problem, but how do I set the `File` Object to them? From what I understand, this is not possible... To recap again, I have an `Array` of `File` Objects. I can certainly use javascript to add an `` element to my form for each one of these `File`s, but I cannot set its [value](https://stackoverflow.com/questions/1696877/how-to-set-a-value-to-a-file-input-in-html?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa). – theyuv Apr 12 '18 at 09:14
  • 2
    So get creative: let the user select a file, move the hidden `` (which has its value set) inside the `
    `, then create a new hidden one. https://jsfiddle.net/khrismuc/bke2nat3/ (btw, your comment that says "cannot set its value" clarifies your issue MUCH better than your edit)
    –  Apr 12 '18 at 09:33
  • That sounds doable I think. Thanks! – theyuv Apr 12 '18 at 10:35
  • @ChrisG Do you have any ideas for how to do this with a "multiple" input and also have the "remove" option? Slightly different from your jsfiddle, I print the file names to the page and allow the user to remove them. If they've uploaded (eg) 3 files at once, and then click "remove" on one of them, I can't remove only one from the element. – theyuv Apr 12 '18 at 11:57
  • I didn't want to spend an hour on this, essentially doing your work for you. Anyway, I don't think you can use `multiple` for this. And removing works by changing the existing mechanism so it looks for the corresponding `` inside the form and removes it. –  Apr 12 '18 at 16:46

1 Answers1

2

The only way to submit the FormData Object is via Ajax

This is not true.

A FormData object is simply a way of encoding binary data before transfer (see MDN for a full outline of its purpose). It is only really required when sending files (ie. binary data) to the server.

If you want to do that without AJAX, add the enctype="multipart/form-data" attribute to your form element and submit it as usual.

Also note that the use of FormData has nothing to do with security, as your question title implies.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • How do I attach the `FormData` object to the form? I created the `FormData` Object in the client side code. The `form` doesn't know about it yet. – theyuv Apr 12 '18 at 08:25
  • You don't need to. You only need to build the `FormData` manually for an AJAX request. If you don't want (or need) to use AJAX, then just add the `enctype` attribute I mentioned above to the `
    ` and the browser will encode the data for you before submission.
    – Rory McCrossan Apr 12 '18 at 08:26
  • Please read the second paragraph of the question (including the link). The `input` element on the `form` does not accurately represent the user's selections. I allow the user to add/remove files. I do this by creating my own `Array` of `File` Objects in the client side code. This new array of `File` Objects needs to be sent with the request. This is possible with Ajax, not with regular form submit; why? – theyuv Apr 12 '18 at 08:31