FormData not appending the data - javascript

I am just scratching my head, and do not understand, what happens here. This code has worked both in production and in my developer environment.
Here is the reference, I do exactly the same.
var fileToUpload = $('#productsFile').prop('files')[0];
var formData = new FormData();
formData.append('file', fileToUpload);
formData.append('action', 'csvUpload');
formData.append('siteId', $('#siteId').val());
console.log($('#siteId').val());
console.log(fileToUpload);
console.log(formData);
The output in the console:
10
File { name: "H00447.PriceList.csv", lastModified: 1464960003935, lastModifiedDate: Date 2016-06-03T13:20:03.935Z, size: 14859917, type: "application/vnd.ms-excel" }
FormData { }
Object has created, the values are fine, so what could be the problem here? Tested with Firefox Developer Edition.
EDIT
Here is the code to send the data to the ajax:
$.ajax({
url: ajaxUrl, // point to server-side PHP script
dataType: 'text', // what to expect back from the PHP script, if anything
cache: false,
contentType: false,
processData: false,
data: formData,
type: 'post'
}).done(function (msg) {
if (parseInt(msg) !== 0) {
alert(msg);
} else {
location.reload();
}
}).fail(function (msg) {
alert('Error: ' + msg.statusText);
});
In the ajax.php I just var_dump($_REQUEST); and shows me an empty array.
EDIT2
I tried it on another localhost environment, I've just added some random keys and values, and everything was fine, even in FF and Chrome.
So I came back to this issue, and just commented out the fileToUpload section.
The other two value was in the $_POST. If I add the file, the $_POST will be empty.
Something wrong with the file.
EDIT3
No I just tested it with a small file, what is about 3-4Kb, and everything is fine. My production file is 14Mb, I think that will be the problem.
SOLUTION
This whole thing because of the filesize. I incrased the post limit, and max file size in php.ini and viola. Things are works. Thank you for your help.

Try this to log keys and values:
formData.forEach(function (value, key) {
console.log(key, value);
});

The data is send but you need to use POST not GET:
var formData = new FormData();
formData.append('action', 'csvUpload');
var xhr = new XMLHttpRequest();
xhr.open("POST", "ajax.php", true);
xhr.send(formData);

Related

How can I pass the file when click submit button javascript? [duplicate]

I've got a problem sending a file to a serverside PHP-script using jQuery's ajax-function.
It's possible to get the File-List with $('#fileinput').attr('files') but how is it possible to send this Data to the server? The resulting array ($_POST) on the serverside php-script is 0 (NULL) when using the file-input.
I know it is possible (though I didn't find any jQuery solutions until now, only Prototye code (http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html)).
This seems to be relatively new, so please do not mention file upload would be impossible via XHR/Ajax, because it's definitely working.
I need the functionality in Safari 5, FF and Chrome would be nice but are not essential.
My code for now is:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Starting with Safari 5/Firefox 4, it’s easiest to use the FormData class:
var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
So now you have a FormData object, ready to be sent along with the XMLHttpRequest.
jQuery.ajax({
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
});
It’s imperative that you set the contentType option to false, forcing jQuery not to add a Content-Type header for you, otherwise, the boundary string will be missing from it.
Also, you must leave the processData flag set to false, otherwise, jQuery will try to convert your FormData into a string, which will fail.
You may now retrieve the file in PHP using:
$_FILES['file-0']
(There is only one file, file-0, unless you specified the multiple attribute on your file input, in which case, the numbers will increment with each file.)
Using the FormData emulation for older browsers
var opts = {
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
};
if(data.fake) {
// Make sure no text encoding stuff is done by xhr
opts.xhr = function() { var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary; return xhr; }
opts.contentType = "multipart/form-data; boundary="+data.boundary;
opts.data = data.toString();
}
jQuery.ajax(opts);
Create FormData from an existing form
Instead of manually iterating the files, the FormData object can also be created with the contents of an existing form object:
var data = new FormData(jQuery('form')[0]);
Use a PHP native array instead of a counter
Just name your file elements the same and end the name in brackets:
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file[]', file);
});
$_FILES['file'] will then be an array containing the file upload fields for every file uploaded. I actually recommend this over my initial solution as it’s simpler to iterate over.
Look at my code, it does the job for me
$( '#formId' )
.submit( function( e ) {
$.ajax( {
url: 'FormSubmitUrl',
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
} );
e.preventDefault();
} );
Just wanted to add a bit to Raphael's great answer. Here's how to get PHP to produce the same $_FILES, regardless of whether you use JavaScript to submit.
HTML form:
<form enctype="multipart/form-data" action="/test.php"
method="post" class="putImages">
<input name="media[]" type="file" multiple/>
<input class="button" type="submit" alt="Upload" value="Upload" />
</form>
PHP produces this $_FILES, when submitted without JavaScript:
Array
(
[media] => Array
(
[name] => Array
(
[0] => Galata_Tower.jpg
[1] => 518f.jpg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
)
[tmp_name] => Array
(
[0] => /tmp/phpIQaOYo
[1] => /tmp/phpJQaOYo
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 258004
[1] => 127884
)
)
)
If you do progressive enhancement, using Raphael's JS to submit the files...
var data = new FormData($('input[name^="media"]'));
jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
data.append(i, file);
});
$.ajax({
type: ppiFormMethod,
data: data,
url: ppiFormActionURL,
cache: false,
contentType: false,
processData: false,
success: function(data){
alert(data);
}
});
... this is what PHP's $_FILES array looks like, after using that JavaScript to submit:
Array
(
[0] => Array
(
[name] => Galata_Tower.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpAQaOYo
[error] => 0
[size] => 258004
)
[1] => Array
(
[name] => 518f.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpBQaOYo
[error] => 0
[size] => 127884
)
)
That's a nice array, and actually what some people transform $_FILES into, but I find it's useful to work with the same $_FILES, regardless if JavaScript was used to submit. So, here are some minor changes to the JS:
// match anything not a [ or ]
regexp = /^[^[\]]+/;
var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );
// make files available
var data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
data.append(fileInputName+'['+i+']', file);
});
(14 April 2017 edit: I removed the form element from the constructor of FormData() -- that fixed this code in Safari.)
That code does two things.
Retrieves the input name attribute automatically, making the HTML more maintainable. Now, as long as form has the class putImages, everything else is taken care of automatically. That is, the input need not have any special name.
The array format that normal HTML submits is recreated by the JavaScript in the data.append line. Note the brackets.
With these changes, submitting with JavaScript now produces precisely the same $_FILES array as submitting with simple HTML.
I just built this function based on some info I read.
Use it like using .serialize(), instead just put .serializefiles();.
Working here in my tests.
//USAGE: $("#form").serializefiles();
(function($) {
$.fn.serializefiles = function() {
var obj = $(this);
/* ADD FILE TO PARAM AJAX */
var formData = new FormData();
$.each($(obj).find("input[type='file']"), function(i, tag) {
$.each($(tag)[0].files, function(i, file) {
formData.append(tag.name, file);
});
});
var params = $(obj).serializeArray();
$.each(params, function (i, val) {
formData.append(val.name, val.value);
});
return formData;
};
})(jQuery);
If your form is defined in your HTML, it is easier to pass the form into the constructor than it is to iterate and add images.
$('#my-form').submit( function(e) {
e.preventDefault();
var data = new FormData(this); // <-- 'this' is your form element
$.ajax({
url: '/my_URL/',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
...
Devin Venable's answer was close to what I wanted, but I wanted one that would work on multiple forms, and use the action already specified in the form so that each file would go to the right place.
I also wanted to use jQuery's on() method so I could avoid using .ready().
That got me to this:
(replace formSelector with your jQuery selector)
$(document).on('submit', formSelecter, function( e ) {
e.preventDefault();
$.ajax( {
url: $(this).attr('action'),
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
}).done(function( data ) {
//do stuff with the data you got back.
});
});
If the file input name indicates an array and flags multiple, and you parse the entire form with FormData, it is not necessary to iteratively append() the input files. FormData will automatically handle multiple files.
$('#submit_1').on('click', function() {
let data = new FormData($("#my_form")[0]);
$.ajax({
url: '/path/to/php_file',
type: 'POST',
data: data,
processData: false,
contentType: false,
success: function(r) {
console.log('success', r);
},
error: function(r) {
console.log('error', r);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="my_form">
<input type="file" name="multi_img_file[]" id="multi_img_file" accept=".gif,.jpg,.jpeg,.png,.svg" multiple="multiple" />
<button type="button" name="submit_1" id="submit_1">Not type='submit'</button>
</form>
Note that a regular button type="button" is used, not type="submit". This shows there is no dependency on using submit to get this functionality.
The resulting $_FILES entry is like this in Chrome dev tools:
multi_img_file:
error: (2) [0, 0]
name: (2) ["pic1.jpg", "pic2.jpg"]
size: (2) [1978036, 2446180]
tmp_name: (2) ["/tmp/phphnrdPz", "/tmp/phpBrGSZN"]
type: (2) ["image/jpeg", "image/jpeg"]
Note: There are cases where some images will upload just fine when uploaded as a single file, but they will fail when uploaded in a set of multiple files. The symptom is that PHP reports empty $_POST and $_FILES without AJAX throwing any errors. Issue occurs with Chrome 75.0.3770.100 and PHP 7.0. Only seems to happen with 1 out of several dozen images in my test set.
Nowadays you don't even need jQuery:) fetch API support table
let result = fetch('url', {method: 'POST', body: new FormData(document.querySelector("#form"))})
The FormData class does work, however in iOS Safari (on the iPhone at least) I wasn't able to use Raphael Schweikert's solution as is.
Mozilla Dev has a nice page on manipulating FormData objects.
So, add an empty form somewhere in your page, specifying the enctype:
<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo"></form>
Then, create FormData object as:
var data = new FormData($("#fileinfo"));
and proceed as in Raphael's code.
One gotcha I ran into today I think is worth pointing out related to this problem: if the url for the ajax call is redirected then the header for content-type: 'multipart/form-data' can be lost.
For example, I was posting to http://server.com/context?param=x
In the network tab of Chrome I saw the correct multipart header for this request but then a 302 redirect to http://server.com/context/?param=x (note the slash after context)
During the redirect the multipart header was lost. Ensure requests are not being redirected if these solutions are not working for you.
Older versions of IE do not support FormData ( Full browser support list for FormData is here: https://developer.mozilla.org/en-US/docs/Web/API/FormData).
Either you can use a jquery plugin (For ex, http://malsup.com/jquery/form/#code-samples ) or, you can use IFrame based solution to post multipart form data through ajax: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
All the solutions above are looks good and elegant, but the FormData() object does not expect any parameter, but use append() after instantiate it, like what one wrote above:
formData.append(val.name, val.value);
get form object by jquery-> $("#id")[0]
data = new FormData($("#id")[0]);
ok,data is your want

Retrieve file uploaded in Laravel using JavaScript FormData

Running into a bit of trouble trying to upload multiple files through a single AJAX request into a Laravel 5 back-end.
In the front-end, I am using the following code to prep the FormData object:
var fd = new FormData();
fd.append("data", JSON.stringify(values));
fd.append("page_id", page_id);
files.forEach(function(file, index){
fd.append("file_"+index, file);
});
Then this is my AJAX call:
$.ajax({
type: 'POST',
url: '/file_test',
data: fd,
contentType: false,
processData: false,
success: function(response){
alert(response);
},
failure: function(response){
alert(response);
}
});
In the back-end, I've tried to retrieve with $request->allFiles() and $request->file('file_0') as well as $_FILES but they are all turning up empty.
After #Pavel mentioned that the $_FILES array was empty, I went and checked what was being sent up in the XHRRequest. What I realized was that I was not appending the file itself to the FormData object and instead was appending the whole input containing the file.
var files = [];
if(this.type == "file"){
if(this.files.length == 1){
values[$(this).attr('name')] = this.files[0].name;
//files.push(this); // ORIGINAL CODE
files.push(this.files[0]); // WORKING CODE!
}
}

how to submit multipart form using jquery ajax without formajax plugin and don't want to use hidden iframe? [duplicate]

I've got a problem sending a file to a serverside PHP-script using jQuery's ajax-function.
It's possible to get the File-List with $('#fileinput').attr('files') but how is it possible to send this Data to the server? The resulting array ($_POST) on the serverside php-script is 0 (NULL) when using the file-input.
I know it is possible (though I didn't find any jQuery solutions until now, only Prototye code (http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html)).
This seems to be relatively new, so please do not mention file upload would be impossible via XHR/Ajax, because it's definitely working.
I need the functionality in Safari 5, FF and Chrome would be nice but are not essential.
My code for now is:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Starting with Safari 5/Firefox 4, it’s easiest to use the FormData class:
var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
So now you have a FormData object, ready to be sent along with the XMLHttpRequest.
jQuery.ajax({
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
});
It’s imperative that you set the contentType option to false, forcing jQuery not to add a Content-Type header for you, otherwise, the boundary string will be missing from it.
Also, you must leave the processData flag set to false, otherwise, jQuery will try to convert your FormData into a string, which will fail.
You may now retrieve the file in PHP using:
$_FILES['file-0']
(There is only one file, file-0, unless you specified the multiple attribute on your file input, in which case, the numbers will increment with each file.)
Using the FormData emulation for older browsers
var opts = {
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
};
if(data.fake) {
// Make sure no text encoding stuff is done by xhr
opts.xhr = function() { var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary; return xhr; }
opts.contentType = "multipart/form-data; boundary="+data.boundary;
opts.data = data.toString();
}
jQuery.ajax(opts);
Create FormData from an existing form
Instead of manually iterating the files, the FormData object can also be created with the contents of an existing form object:
var data = new FormData(jQuery('form')[0]);
Use a PHP native array instead of a counter
Just name your file elements the same and end the name in brackets:
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file[]', file);
});
$_FILES['file'] will then be an array containing the file upload fields for every file uploaded. I actually recommend this over my initial solution as it’s simpler to iterate over.
Look at my code, it does the job for me
$( '#formId' )
.submit( function( e ) {
$.ajax( {
url: 'FormSubmitUrl',
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
} );
e.preventDefault();
} );
Just wanted to add a bit to Raphael's great answer. Here's how to get PHP to produce the same $_FILES, regardless of whether you use JavaScript to submit.
HTML form:
<form enctype="multipart/form-data" action="/test.php"
method="post" class="putImages">
<input name="media[]" type="file" multiple/>
<input class="button" type="submit" alt="Upload" value="Upload" />
</form>
PHP produces this $_FILES, when submitted without JavaScript:
Array
(
[media] => Array
(
[name] => Array
(
[0] => Galata_Tower.jpg
[1] => 518f.jpg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
)
[tmp_name] => Array
(
[0] => /tmp/phpIQaOYo
[1] => /tmp/phpJQaOYo
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 258004
[1] => 127884
)
)
)
If you do progressive enhancement, using Raphael's JS to submit the files...
var data = new FormData($('input[name^="media"]'));
jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
data.append(i, file);
});
$.ajax({
type: ppiFormMethod,
data: data,
url: ppiFormActionURL,
cache: false,
contentType: false,
processData: false,
success: function(data){
alert(data);
}
});
... this is what PHP's $_FILES array looks like, after using that JavaScript to submit:
Array
(
[0] => Array
(
[name] => Galata_Tower.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpAQaOYo
[error] => 0
[size] => 258004
)
[1] => Array
(
[name] => 518f.jpg
[type] => image/jpeg
[tmp_name] => /tmp/phpBQaOYo
[error] => 0
[size] => 127884
)
)
That's a nice array, and actually what some people transform $_FILES into, but I find it's useful to work with the same $_FILES, regardless if JavaScript was used to submit. So, here are some minor changes to the JS:
// match anything not a [ or ]
regexp = /^[^[\]]+/;
var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );
// make files available
var data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
data.append(fileInputName+'['+i+']', file);
});
(14 April 2017 edit: I removed the form element from the constructor of FormData() -- that fixed this code in Safari.)
That code does two things.
Retrieves the input name attribute automatically, making the HTML more maintainable. Now, as long as form has the class putImages, everything else is taken care of automatically. That is, the input need not have any special name.
The array format that normal HTML submits is recreated by the JavaScript in the data.append line. Note the brackets.
With these changes, submitting with JavaScript now produces precisely the same $_FILES array as submitting with simple HTML.
I just built this function based on some info I read.
Use it like using .serialize(), instead just put .serializefiles();.
Working here in my tests.
//USAGE: $("#form").serializefiles();
(function($) {
$.fn.serializefiles = function() {
var obj = $(this);
/* ADD FILE TO PARAM AJAX */
var formData = new FormData();
$.each($(obj).find("input[type='file']"), function(i, tag) {
$.each($(tag)[0].files, function(i, file) {
formData.append(tag.name, file);
});
});
var params = $(obj).serializeArray();
$.each(params, function (i, val) {
formData.append(val.name, val.value);
});
return formData;
};
})(jQuery);
If your form is defined in your HTML, it is easier to pass the form into the constructor than it is to iterate and add images.
$('#my-form').submit( function(e) {
e.preventDefault();
var data = new FormData(this); // <-- 'this' is your form element
$.ajax({
url: '/my_URL/',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
...
Devin Venable's answer was close to what I wanted, but I wanted one that would work on multiple forms, and use the action already specified in the form so that each file would go to the right place.
I also wanted to use jQuery's on() method so I could avoid using .ready().
That got me to this:
(replace formSelector with your jQuery selector)
$(document).on('submit', formSelecter, function( e ) {
e.preventDefault();
$.ajax( {
url: $(this).attr('action'),
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
}).done(function( data ) {
//do stuff with the data you got back.
});
});
If the file input name indicates an array and flags multiple, and you parse the entire form with FormData, it is not necessary to iteratively append() the input files. FormData will automatically handle multiple files.
$('#submit_1').on('click', function() {
let data = new FormData($("#my_form")[0]);
$.ajax({
url: '/path/to/php_file',
type: 'POST',
data: data,
processData: false,
contentType: false,
success: function(r) {
console.log('success', r);
},
error: function(r) {
console.log('error', r);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="my_form">
<input type="file" name="multi_img_file[]" id="multi_img_file" accept=".gif,.jpg,.jpeg,.png,.svg" multiple="multiple" />
<button type="button" name="submit_1" id="submit_1">Not type='submit'</button>
</form>
Note that a regular button type="button" is used, not type="submit". This shows there is no dependency on using submit to get this functionality.
The resulting $_FILES entry is like this in Chrome dev tools:
multi_img_file:
error: (2) [0, 0]
name: (2) ["pic1.jpg", "pic2.jpg"]
size: (2) [1978036, 2446180]
tmp_name: (2) ["/tmp/phphnrdPz", "/tmp/phpBrGSZN"]
type: (2) ["image/jpeg", "image/jpeg"]
Note: There are cases where some images will upload just fine when uploaded as a single file, but they will fail when uploaded in a set of multiple files. The symptom is that PHP reports empty $_POST and $_FILES without AJAX throwing any errors. Issue occurs with Chrome 75.0.3770.100 and PHP 7.0. Only seems to happen with 1 out of several dozen images in my test set.
Nowadays you don't even need jQuery:) fetch API support table
let result = fetch('url', {method: 'POST', body: new FormData(document.querySelector("#form"))})
The FormData class does work, however in iOS Safari (on the iPhone at least) I wasn't able to use Raphael Schweikert's solution as is.
Mozilla Dev has a nice page on manipulating FormData objects.
So, add an empty form somewhere in your page, specifying the enctype:
<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo"></form>
Then, create FormData object as:
var data = new FormData($("#fileinfo"));
and proceed as in Raphael's code.
One gotcha I ran into today I think is worth pointing out related to this problem: if the url for the ajax call is redirected then the header for content-type: 'multipart/form-data' can be lost.
For example, I was posting to http://server.com/context?param=x
In the network tab of Chrome I saw the correct multipart header for this request but then a 302 redirect to http://server.com/context/?param=x (note the slash after context)
During the redirect the multipart header was lost. Ensure requests are not being redirected if these solutions are not working for you.
Older versions of IE do not support FormData ( Full browser support list for FormData is here: https://developer.mozilla.org/en-US/docs/Web/API/FormData).
Either you can use a jquery plugin (For ex, http://malsup.com/jquery/form/#code-samples ) or, you can use IFrame based solution to post multipart form data through ajax: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
All the solutions above are looks good and elegant, but the FormData() object does not expect any parameter, but use append() after instantiate it, like what one wrote above:
formData.append(val.name, val.value);
get form object by jquery-> $("#id")[0]
data = new FormData($("#id")[0]);
ok,data is your want

Sending blob data via ajax

So I'm trying to send an image via ajax as a blob. The blob has the correct type and is about 4.5 kb in size. I try to send it like this:
document.getElementById("canvas").toBlob(function (blob) {
var data = new FormData();
data.append('name', name);
data.append('program', YouTomaton.Main.get_CurrentProgram());
data.append('image', blob);
$.ajax({
type: "Post",
url: "save.php",
data: data,
processData: false,
contentType: false,
success: function (result) {
if(result != undefined && result.length > 0)
alert(result);
}
});
});
The recieving page looks like this:
<?php
include("session.php");
writeProgram($_POST['name'], $_POST['program'], $_POST['image']);
?>
It tells me that the index 'image' could not be found. So not only does the data not get sent, but even the index is omitted. What am I doing wrong ?
EDIT: neither toBlob nor toDataURL produce anything but an empty PNG. Is there a way to convert the data from a framebuffer into a base64 encoded jpg or png ?
Read this. Then think of what you would like to do.
If you could use a plugin for jQuery. I would recommend using FileUpload
For an HTML file input, minimal syntax would be like this:
<input type="file" name="fs" id="fileupload" />
And JS script:
$('#fileupload').fileupload({
url: "fileupload?additional=data",
done: function (e, data) {
console.log(data.result);
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
I'm working on a similar problem right now - I'm using PDF's - here's my working ajax call:
$.ajax({
dataType: "native",
url: ("handle.php?filename=" + event.target.dataset.name),
xhrFields: { responseType: "blob" },
data: "secure=<?php echo $pass ?>",
success: function(result){
console.log(result.size)
download(result, event.target.dataset.name, "application/pdf")
}
})
The download() part is a call to the FileSaver tool - which is how the Blob gets saved on the client side in my case...
I'm using data-name attr in the markup to store JUST the filename (not full path) - hope that helps!
EDIT:: Sorry for the PHP mixed in! - that statement just passes a hashed nonce token to the script to make sure no requests have been duplicated/gotton out of order - etc...

SharePoint Online REST - Image upload via JavaScript/AJAX

I'm trying to upload an image to SharePoint using native JavaScript/jQuery - NOT SP.RequestExecutor.
I've cracked the authentication issue, nice and easy, so now it's just a case of working out how to upload binary files. If I put plain text in the file, it uploads fine, it's just binary data I'm having trouble with.
My code so far is included below. getToken() does it's thing and leaves me with a valid digest object to use. Also note I've blanked out the document library name with *'s.
function PerformUpload(fileName, fileData) {
getToken();
$.ajax({
url: siteFullUrl +
"/_api/web/GetFolderByServerRelativeUrl('/*****/')/Files" +
"/Add(url='" + fileName + "', overwrite=true)",
type: "POST",
async: false,
data: fileData,
processData: false,
contentType: "application/json;odata=verbose",
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": digest
},
success: function (data) {
alert("Success");
},
error: function (err) {
alert("Error: \r\n" + JSON.stringify(err));
}
});
}
I've tried many combinations of different values for contentType, setting binaryStringRequestBody: true but the image is still corrupt when it comes into SharePoint.
My code at the moment to parse the file into binary is
var reader = new FileReader();
reader.onload = function (result) {
var fileName = '',
libraryName = '',
fileData = '';
var byteArray = new Uint8Array(result.target.result)
for (var i = 0; i < byteArray.byteLength; i++) {
fileData += String.fromCharCode(byteArray[i])
}
PerformUpload("image.jpg", fileData);
};
reader.readAsArrayBuffer(fileInput);
A file is being uploaded to SharePoint but if I try and view or download it it's corrupt.
Can anyone provide any guidance as to the correct way to upload a binary file to SharePoint? I should mention that if I replace (on the ajax call) data: fileData, with data: "A simple string", the file uploads and when I download it the contents of the file are A simple string.
If you are using SP.RequestExecutor to upload the file to SharePoint, you must be converted the ArrayBuffer into a string which can then be set as the body of a POST operation. See details here which guide you how to Upload file to SharePoint using REST by SP.RequestExecutor.
If you are using parsed file into binary with Jquery.Ajax, the image will corrupt when it comes into SharePoint. Also noted that the FileReader object accepts the file information for loading asynchronously. The onload and onerror events fire when the file is loaded successfully or fails. We should keep the proccess of onload event by default and get the result in onloadend event.
I tried the following articles and it work:
How to: Upload a file by using the REST API and jQuery
For simple, here is how I implemented:
var fileInput = jQuery('#getFile');
var file = fileInput[0].files[0];
var serverRelativeUrlToFolder = '*****'; //if the library in subsite, You have to remove the forward slash "/" before the document library relative url.
proccessUploadUsingJQueryAjax(file, serverRelativeUrlToFolder);
function getFileBuffer(file) {
var deferred = jQuery.Deferred();
var reader = new FileReader();
reader.onloadend = function (e) {
deferred.resolve(e.target.result);
}
reader.onerror = function (e) {
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(file);
return deferred.promise();
}
function addFileToFolderUsingJQueryAjax(fileName, arrayBuffer, serverRelativeUrlToFolder) {
// Construct the endpoint.
var fileCollectionEndpoint = String.format(
"{0}/_api/web/GetFolderByServerRelativeUrl('{1}')/files/add(overwrite=true, url='{2}')",
_spPageContextInfo.webAbsoluteUrl, serverRelativeUrlToFolder, fileName);
// Send the request and return the response.
// This call returns the SharePoint file.
return jQuery.ajax({
url: fileCollectionEndpoint,
type: "POST",
data: arrayBuffer,
processData: false,
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
}
});
}
function proccessUploadUsingJQueryAjax(file, serverRelativeUrlToFolder){
var getFile = getFileBuffer(file);
getFile.done(function (arrayBuffer) {
// Add the file to the SharePoint folder.
var addFile = addFileToFolderUsingJQueryAjax("image.jpg", arrayBuffer, serverRelativeUrlToFolder);
addFile.done(function (file, status, xhr) {
alert("File Uploaded");
});
addFile.fail(function (error) { alert("Error Add File: " + error.responseText); });
});
getFile.fail(function (error) { alert("Error Get File: " + error.responseText); });
}
Please let me know if it solved your problem.
Try adding this to your ajax settings
transformRequest: []
this will prevent Sharepoint from adding metadata to your file

Categories

Resources