Setting a file upload field value - Javascript/jQuery [duplicate]
Asked Answered
C

8

15

I have a form page that has a file upload field and I am trying to set the value of that field programmatically and although I know that it isn't possible due to security reasons, I would like to know if we still can? If there is a plugin or something that I could use to perform the upload. I have the Base64 value of the file field that is required to set that field, all I need to know is if there is a way to set it.

Any suggestions or help would be great in this regard.

Thanks.

Update: Added a JsFiddle to demonstrate what I'm trying out.

Please visit this website to create a text file using the example in the js fiddle and convert it using this link.

var str = `text`;

http://www.motobit.com/util/base64-decoder-encoder.asp

JsFiddle

Note:

The answer(s) below reflect the state of legacy browsers in 2009. Now you can actually set the value of the file input element dynamically/programatically using JavaScript in 2017.

See the answer in this question for details as well as a demo:
How to set file input value programatically (i.e.: when drag-dropping files)?

Couldst answered 22/8, 2016 at 9:8 Comment(1)
"I have the Base64 value of the file field" How is the base64 or data URI representation of file retrieved?Skunk
T
5

You can convert the base64 string to a blob and then add it to the formData before submitting it with an ajax request:

$("#form").submit(function(e) {
  e.preventDefault();
  formData = new FormData($(this)[0]);
  var blob = dataURLtoBlob("base64 string");
  formData.append("yourfile", blob);
  $.ajax({
    url: "whatever.php",
    type: "POST",
    data: formData,
    contentType: false,
    cache: false,
    processData: false,
    success: function(data) {
      alert("Form has been submitted with file");
    }
});

dataURLtoBlob is a function that converts the base64 string to the binary file (blob) source: Blob from DataURL?

Trantham answered 24/8, 2016 at 17:10 Comment(27)
Is a blob, a minified version of the base64 string?Couldst
No it's the binary version, so you don't need to decode it or something server side. Base64 is a form of encoding, encoding always adds overhead and increases the size.Trantham
Ok so if I use a file of size 10 MB (for example), what's the blob size going to be like? Do you know how many characters it would roughly contain?Couldst
Also in that example atob("base64 string") would only work if the file has been encoded using btoa("normal file")Couldst
The blob size would be 10MB since the blob just contains the raw file data, the base64 size would be around 14MB.Trantham
I am getting an error when trying to get the conversion done using atob() because my original b64 string hasn't been converted using btoa().Couldst
Can you convert the original string using btoa and compare both b64 strings? Sometimes the difference is in a extra character at the beginning and/or end.Trantham
Its actually a file, lets say an image file so its not really a string if you know what I mean.Couldst
I know but if you create a base64 string using your current method and using btoa and compare both base 64 strings, maybe the difference between those is something that can be solved with javascript.Trantham
Question is: How do I pass the file to atob(...) to get its b64 value?Couldst
#6978656Trantham
Cool.. There is an issue though. It doesn't return the complete b64 string. It truncates after a certain point. I used multiple sentences as my string and tried to perform an atob() and it did return the b64 value but not the complete value.Couldst
The console.log() functions is probably truncating the string. Use substring to get the first and last 1000 characters. Then compare those, can you post the string on jsfiddle or something so I can take a look at it and compare?Trantham
Sure, I'll add that in a JSFiddle.Couldst
I have added my jsfiddle to the question. Like you said, there is a difference of a few characters towards the end when performing the conversion. Please have a look and tell me how this can be resolved.Couldst
The difference is probably due to the character/new line encoding but shouldn;t cause any issues :/ can you try the following instead of atob: atob(str.replace(/\s/g, "")); It might also be an issue with whitespace in the base64 string. If whitespace isn't the problem then it's probably the character encoding which is hopefully not the case since fixing that is a nuisance.Trantham
@Trantham Note, convertedvalue at jsfiddle.net/rccfymrz/10 is a base64 string, not a data URISkunk
@Trantham Note also, done is not an $.ajax() option; syntax error at ; following done: function(data) { alert("Form has been submitted with file"); };Skunk
My bad wrote the done method as callback by accident.Trantham
@Trantham convertedvalue at jsfiddle.net/rccfymrz/10 is not a valid data URI, see Data URIsSkunk
@Skunk I know that a datauri requires a data type but a base64 string by itself is not a datauri neither does btoa require a specific datauri as far I remember.Trantham
@Trantham "dataURLtoBlob is a function that converts the base64 string to the binary file" The function used at Answer, dataURItoBlob linked from https://mcmap.net/q/41998/-blob-from-dataurl , expects a valid data URI as parameter, not base64 string alone. Note, missing last s at succes at updated AnswerSkunk
@Skunk Oh my bad I thought it only required a base64 string, since it works with a base64 string when I used the function before but it seems that's just a feature depending on the browser and not a standard. I fixed the s, english is not my first language :PTrantham
@seahorsepip: I don't know the url where the ajax is supposed to take you to upon submit as this is something that is not under my control. How do you think I can achieve that?Couldst
@JackBrown if you have a normal form that you want to replace with ajax just look at the action attribute of the form. If there is no action attribute then the url is the same as the page that contains the form.Trantham
Yes, there is an action attribute. How would the above code change since that is the scenario?Couldst
@JackBrown Replace "whatever.php" with the url in the action attribute.Trantham
S
1

Update: Added a JsFiddle to demonstrate what I'm trying out.

@seahorsepip Answer, minimally adjusted to substitute success for done which is not a defined $.ajax() setting, and removing trailing ; following done:function(){}, which logs a syntax error, should return expected result. Where convertedvalue at linked jsfiddle at updated Question is also adjusted to a valid data URI. That is, after converting string to base64, use the "data" URL scheme to convert base64 string to valid data URI; e.g.,

"data:text/plain;base64," + convertedvalue

Note, File object created at FormData is requested with GET and returned at success at stacksnippets and jsfiddle to demonstrate file within FormData POSTed by $.ajax()

var convertedvalue = btoa(str); // where `str` is string
$("#form").submit(function(e) {
  e.preventDefault();
  formData = new FormData($(this)[0]);
  // pass valid `data URI` to `dataURItoBlob`
  // note `base64` extension
  var blob = dataURItoBlob("data:text/plain;base64," + convertedvalue);
  formData.append("yourfile", blob);
  $.ajax({
    url: "/path/to/server",
    type: "POST",
    data: formData,
    contentType: false,
    cache: true,
    processData: false,
    // substitute `success` for `done`
    success: function(data) {
      //alert("Form has been submitted with file");
    } // remove trailing `;`
  });
})

var str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit pharetra ante, quis tristique elit tempor at. Mauris nec nisi porttitor, sodales nunc facilisis, tempor ligula. Aenean luctus purus id orci commodo, eu ornare erat molestie. Proin viverra semper est, sit amet hendrerit mi. Phasellus sodales auctor ipsum eu fermentum. Quisque ut convallis turpis. Suspendisse et varius lorem. Quisque ipsum metus, venenatis quis aliquam et, lobortis nec purus. Aenean consectetur, tellus in gravida tempor, dui lacus placerat dui, quis dictum libero sapien at diam. Donec eleifend, turpis ac vulputate vulputate, nulla enim vestibulum magna, nec finibus ex urna sed quam. Curabitur vitae felis mi. Suspendisse potenti.

Quisque scelerisque mattis venenatis. Phasellus in varius lectus. Ut ut lorem eu augue convallis vulputate. Ut at tortor leo. Etiam tristique, quam et ultrices commodo, risus mauris mollis nisi, quis condimentum sapien tortor et dolor. Pellentesque sollicitudin velit ut sapien tristique, in mattis est facilisis. Pellentesque et leo massa. Sed pretium faucibus purus ac sodales. Sed varius eros felis, vel posuere metus lobortis id. Maecenas eget cursus ligula. In nec luctus orci. Nunc sed massa elit. Pellentesque iaculis tortor sit amet tellus ultrices, nec tristique lorem semper.

Donec aliquet ipsum ipsum, in consequat nisl euismod nec. Aenean aliquam nisl nec elit convallis pulvinar. Suspendisse ac malesuada ex. Fusce laoreet metus at nulla suscipit, non facilisis dui scelerisque. Maecenas blandit augue et lorem venenatis consequat. In porttitor eros ac elit placerat sodales. Suspendisse facilisis lorem vestibulum ante commodo dignissim. Mauris dignissim egestas massa, sit amet hendrerit orci molestie id. Suspendisse vel enim sit amet massa eleifend accumsan. Curabitur eleifend velit non nisi egestas ornare. Ut congue, eros a condimentum faucibus, risus sapien cursus elit, tempor condimentum nisi nisi vitae leo. Sed quis blandit tellus, in aliquet purus. Pellentesque eget leo lobortis, consectetur nisi non, facilisis lectus. Morbi tortor augue, posuere vel ultrices in, vestibulum vel nibh. Morbi accumsan tellus congue commodo tincidunt.

Curabitur vitae fermentum eros. Sed ex dolor, suscipit in ornare in, sollicitudin ac mi. Phasellus ornare ipsum vel elit mollis convallis. Nunc nec porttitor tellus. Nullam volutpat leo sed dapibus vestibulum. Ut aliquet accumsan nulla, commodo pharetra urna auctor in. In ligula lectus, molestie a libero a, sollicitudin rutrum tellus.

Integer vitae turpis id ligula eleifend laoreet. Morbi molestie libero non interdum pulvinar. Nulla facilisi. Nulla a facilisis velit. Etiam metus felis, fermentum eget massa eu, posuere vestibulum mauris. Donec placerat faucibus sapien, vitae dapibus est dapibus ac. Nam quis elementum eros, a eleifend erat. Sed interdum nisi at rhoncus rutrum. Phasellus vitae arcu a tellus tincidunt mattis.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit pharetra ante, quis tristique elit tempor at. Mauris nec nisi porttitor, sodales nunc facilisis, tempor ligula. Aenean luctus purus id orci commodo, eu ornare erat molestie. Proin viverra semper est, sit amet hendrerit mi. Phasellus sodales auctor ipsum eu fermentum. Quisque ut convallis turpis. Suspendisse et varius lorem. Quisque ipsum metus, venenatis quis aliquam et, lobortis nec purus. Aenean consectetur, tellus in gravida tempor, dui lacus placerat dui, quis dictum libero sapien at diam. Donec eleifend, turpis ac vulputate vulputate, nulla enim vestibulum magna, nec finibus ex urna sed quam. Curabitur vitae felis mi. Suspendisse potenti.

Quisque scelerisque mattis venenatis. Phasellus in varius lectus. Ut ut lorem eu augue convallis vulputate. Ut at tortor leo. Etiam tristique, quam et ultrices commodo, risus mauris mollis nisi, quis condimentum sapien tortor et dolor. Pellentesque sollicitudin velit ut sapien tristique, in mattis est facilisis. Pellentesque et leo massa. Sed pretium faucibus purus ac sodales. Sed varius eros felis, vel posuere metus lobortis id. Maecenas eget cursus ligula. In nec luctus orci. Nunc sed massa elit. Pellentesque iaculis tortor sit amet tellus ultrices, nec tristique lorem semper.

Donec aliquet ipsum ipsum, in consequat nisl euismod nec. Aenean aliquam nisl nec elit convallis pulvinar. Suspendisse ac malesuada ex. Fusce laoreet metus at nulla suscipit, non facilisis dui scelerisque. Maecenas blandit augue et lorem venenatis consequat. In porttitor eros ac elit placerat sodales. Suspendisse facilisis lorem vestibulum ante commodo dignissim. Mauris dignissim egestas massa, sit amet hendrerit orci molestie id. Suspendisse vel enim sit amet massa eleifend accumsan. Curabitur eleifend velit non nisi egestas ornare. Ut congue, eros a condimentum faucibus, risus sapien cursus elit, tempor condimentum nisi nisi vitae leo. Sed quis blandit tellus, in aliquet purus. Pellentesque eget leo lobortis, consectetur nisi non, facilisis lectus. Morbi tortor augue, posuere vel ultrices in, vestibulum vel nibh. Morbi accumsan tellus congue commodo tincidunt.

Curabitur vitae fermentum eros. Sed ex dolor, suscipit in ornare in, sollicitudin ac mi. Phasellus ornare ipsum vel elit mollis convallis. Nunc nec porttitor tellus. Nullam volutpat leo sed dapibus vestibulum. Ut aliquet accumsan nulla, commodo pharetra urna auctor in. In ligula lectus, molestie a libero a, sollicitudin rutrum tellus.

Integer vitae turpis id ligula eleifend laoreet. Morbi molestie libero non interdum pulvinar. Nulla facilisi. Nulla a facilisis velit. Etiam metus felis, fermentum eget massa eu, posuere vestibulum mauris. Donec placerat faucibus sapien, vitae dapibus est dapibus ac. Nam quis elementum eros, a eleifend erat. Sed interdum nisi at rhoncus rutrum. Phasellus vitae arcu a tellus tincidunt mattis.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit pharetra ante, quis tristique elit tempor at. Mauris nec nisi porttitor, sodales nunc facilisis, tempor ligula. Aenean luctus purus id orci commodo, eu ornare erat molestie. Proin viverra semper est, sit amet hendrerit mi. Phasellus sodales auctor ipsum eu fermentum. Quisque ut convallis turpis. Suspendisse et varius lorem. Quisque ipsum metus, venenatis quis aliquam et, lobortis nec purus. Aenean consectetur, tellus in gravida tempor, dui lacus placerat dui, quis dictum libero sapien at diam. Donec eleifend, turpis ac vulputate vulputate, nulla enim vestibulum magna, nec finibus ex urna sed quam. Curabitur vitae felis mi. Suspendisse potenti.

Quisque scelerisque mattis venenatis. Phasellus in varius lectus. Ut ut lorem eu augue convallis vulputate. Ut at tortor leo. Etiam tristique, quam et ultrices commodo, risus mauris mollis nisi, quis condimentum sapien tortor et dolor. Pellentesque sollicitudin velit ut sapien tristique, in mattis est facilisis. Pellentesque et leo massa. Sed pretium faucibus purus ac sodales. Sed varius eros felis, vel posuere metus lobortis id. Maecenas eget cursus ligula. In nec luctus orci. Nunc sed massa elit. Pellentesque iaculis tortor sit amet tellus ultrices, nec tristique lorem semper.

Donec aliquet ipsum ipsum, in consequat nisl euismod nec. Aenean aliquam nisl nec elit convallis pulvinar. Suspendisse ac malesuada ex. Fusce laoreet metus at nulla suscipit, non facilisis dui scelerisque. Maecenas blandit augue et lorem venenatis consequat. In porttitor eros ac elit placerat sodales. Suspendisse facilisis lorem vestibulum ante commodo dignissim. Mauris dignissim egestas massa, sit amet hendrerit orci molestie id. Suspendisse vel enim sit amet massa eleifend accumsan. Curabitur eleifend velit non nisi egestas ornare. Ut congue, eros a condimentum faucibus, risus sapien cursus elit, tempor condimentum nisi nisi vitae leo. Sed quis blandit tellus, in aliquet purus. Pellentesque eget leo lobortis, consectetur nisi non, facilisis lectus. Morbi tortor augue, posuere vel ultrices in, vestibulum vel nibh. Morbi accumsan tellus congue commodo tincidunt.

Curabitur vitae fermentum eros. Sed ex dolor, suscipit in ornare in, sollicitudin ac mi. Phasellus ornare ipsum vel elit mollis convallis. Nunc nec porttitor tellus. Nullam volutpat leo sed dapibus vestibulum. Ut aliquet accumsan nulla, commodo pharetra urna auctor in. In ligula lectus, molestie a libero a, sollicitudin rutrum tellus.

Integer vitae turpis id ligula eleifend laoreet. Morbi molestie libero non interdum pulvinar. Nulla facilisi. Nulla a facilisis velit. Etiam metus felis, fermentum eget massa eu, posuere vestibulum mauris. Donec placerat faucibus sapien, vitae dapibus est dapibus ac. Nam quis elementum eros, a eleifend erat. Sed interdum nisi at rhoncus rutrum. Phasellus vitae arcu a tellus tincidunt mattis.


Images:
1) Copy and replace the following files in the /images folder
        i.      1icon.png
        ii.     2icon.png
        iii.        3icon.png
        iv.     mobil-app.png
        v.      mobil-app-this.png
        vi.     properties-icon.svgz
        vii.        setupLogo.svgz
        viii.       web-app.png
        ix.     web-app-this.png`;
var convertedvalue = btoa(str);
console.log(convertedvalue);
$("#b64text").html(convertedvalue);
$("input[type=submit]").prop("disabled", false);
function dataURItoBlob(dataURI) {
  // convert base64 to raw binary data held in a string
  // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
  var byteString = atob(dataURI.split(',')[1]);

  // separate out the mime component
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

  // write the bytes of the string to an ArrayBuffer
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }

  // write the ArrayBuffer to a blob, and you're done
  var blob = new Blob([ab], {
    type: mimeString
  });
  return blob;

  // Old code
  // var bb = new BlobBuilder();
  // bb.append(ab);
  // return bb.getBlob(mimeString);
}

$("#form").submit(function(e) {
  e.preventDefault();
  formData = new FormData($(this)[0]);
  // pass valid `data URI` to `dataURItoBlob`
  var blob = dataURItoBlob("data:text/plain;base64," + convertedvalue);
  formData.append("yourfile", blob);
  $.ajax({
    url: URL.createObjectURL(formData.get("yourfile")),
    type: "GET",
    // data: formData,
    contentType: false,
    cache: true,
    processData: false,
    success: function(data) {
      console.log(data);
      $("#b64text").html(data);
      //alert("Form has been submitted with file");
    }
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<form id="form">
  <input type="submit" disabled/>
</form>
<div id="b64text" style="  word-wrap: break-word;">

</div>

jsfiddle https://jsfiddle.net/rccfymrz/17/

Skunk answered 31/8, 2016 at 7:17 Comment(2)
Thanks for the jsfiddle, the converted value is missing the line breaks etc. Is that how it is supposed to return the data back?Couldst
@IK Use <pre> element instead of <div> to render result jsfiddle.net/rccfymrz/18Skunk
R
0

The easiest way is to do an AJAX POST request to the form's action field on the <form> tag. This is what the normal HTML does on its own anyways, but in our case you can specify the data programmatically, in this case a multipart file.

For an example, see this question.

Runagate answered 24/8, 2016 at 12:56 Comment(0)
L
0

It is that simple: file type input accepts the path to file, that would be sent on form submit, not the file itself.

UPD: Well, currently it's a little bit more complex (File API), however this is just meant to give you access to the data the user wants to give you.

You don't actually need to mess with file input to send the file.

If you are the one that owns server, you always can accept base64 string from regular text input field as a valid file (as an alternative to regular file field).

Otherwise you can always use ajax (with text or blob) to send your form.

Laith answered 25/8, 2016 at 12:30 Comment(3)
Text input field cannot have more than a certain number of characters where as b64 string value can be huge depending on the file size.Couldst
It seems, that default input max-length is 512k (as in #8545876), however, as I understand, you still can manually increase the limit by setting max-length to a bigger number. Alternatively you can use textarea instead. Btw files of which sizes are we talking about?Laith
A file of size 10 MB will give you roughly 12 million characters as b64 string.Couldst
C
0

Simple fileupload without submit form.

HTML

<input id="inputfileUpload" onchange="fileChanged(this);" type="file" accept="*/*" />

JAVACRIPT

function fileChanged(element) {
  if (element.files[0]) {
    var file = element.files[0];
    var reader = new FileReader();
    reader.onload = function (e) {
      //file.name
      //file.size
                
      //Filedata: e.target.result
      //You can convert to base64
      //Angular sample:
      //$base64.encode(e.target.result);
    };
    reader.readAsBinaryString(file);
 }
}
Churchless answered 29/8, 2016 at 13:43 Comment(0)
C
0

I have the Base64 value of the file field [...] I need to know is if there is a way to set it.

Wouldn't be possible to have an hidden input ? You set the base64 to that field, as the maximum size of an input type="hidden" is the same as type="file"

This way, you avoid the security reasons preventing you to load the local file, and still let you send the base64 representation. The only problem is, we don't know how you have this base64 string. Is it loaded from a request ? Already populated from php ? ...

Carrington answered 30/8, 2016 at 15:19 Comment(6)
It's a bit tricky to explain but the base64 string is coming from vb.net using this function. However, for example purposes we can use btoa() for this question. Do you think using a hidden input would help? Could you modify the jsfiddle I have attached to my question and demonstrate this scenario to me please? #10739764Couldst
I have updated your jsFiddle jsfiddle.net/rccfymrz/12, I used the btoa() function, and all I did was to set an invisible field the base64 value. The maximum size allowed is the same for other fields types (such as File) so not a problem.Carrington
Small files with little text is not an issue. Its only when you have an image lets say that gives out a lot of b64 string value and getting this into the hidden field would get really tricky. Could you provide that in your example please?Couldst
Here is an edited version with 71680 chars jsfiddle.net/rccfymrz/14 Please read here for the char limitations https://mcmap.net/q/717917/-how-many-characters-are-possible-in-an-input-field-in-html (Edit: 716 800 chars here jsfiddle.net/rccfymrz/15 )Carrington
But the question really is would it work fine for an image that has a size of lets say 10 MB? I doubt it would fit in the complete b64 value in that hidden field. Could you use that image and update the jsfiddle please?upload.wikimedia.org/wikipedia/commons/f/ff/…Couldst
I won't be able to do such thing as jsFiddle has its own chars limitations QuotaExceededError: Failed to execute 'setItem' on 'Storage': Setting the value of 'draft[279199281]' exceeded the quota. :-/ Also the site to convert to Base64 also have a limitation The Form.SizeLimit is 10000000bytes But well, you'll have to make the customer to wait the same way the file is uploaded to the browser when the file becomes bigCarrington
T
-1

Use jquery:

$('#file_id_here').attr({'value':'file_path_here'})
Trilobite answered 10/11, 2017 at 21:26 Comment(0)
I
-2

If you just want to set what file is going to be the value of your file input field, you cannot. But you can set the field to blank for form validation reasons try using JavaScript:

document.getElementById("your-file-form-field-id").value = "";
Impetus answered 24/8, 2016 at 17:19 Comment(3)
NO this code won't work! Because this would enable javascript on a website to set a hidden file input field to a value themself resulting in a webpage to be able to get ANY file from a visitors device on form submit...Trantham
"for no reason"? Your code doesn't work neither will such method ever work in the future since browsers don't allow you to change the paths of file inputs because of obvious security reasons.Trantham
@MaxAlexanderHanna , @Trantham is right, it's not possible to set the value of an input type="file" See, for example, #1697377 and #1017724Carrington

© 2022 - 2024 — McMap. All rights reserved.