Appended files to FormData not received at Laravel server - javascript

I'm facing a strange issue ... I've a form with multiple fields .. on form submit, I append multiple image files to form data and submit it like this:
$('#newEntry').on('submit', function(e){
e.preventDefault();
const formData = new FormData(e.target);
formData.delete('images[]');
for (var i = 0; i < filesToUpload.length; i++) {
formData.append('images[]', filesToUpload[i].file, filesToUpload[i].file.name);
}
$(this)[0].submit();
});
and when I try to echo(count($request->images)) at Laravel server it echos 0 .. and on dd($request) .. I see empty files array
but when I submit same form with same files directly from input field instead of appending data to it like this:
<input type="file" name="images[]">
I receive all files at server.
Files are successfully appended to formData .. I've checked it by:
var formKeys = formData.keys();
var formEntries = formData.entries();
do {
console.log(formEntries.next().value);
} while (!formKeys.next().done)
I've also tried to send same appended files through AJAX and it worked perfectly fine:
$('#newEntry').on('submit', function(e){
e.preventDefault();
const formData = new FormData(e.target);
formData.delete('images[]');
for (var i = 0; i < filesToUpload.length; i++) {
formData.append('images[]', filesToUpload[i].file, filesToUpload[i].file.name);
}
$.ajax({
url: actionURL,
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function (data) {
alert("DONE");
},
error: function (data) {
alert("ERROR - " + data.responseText);
}
});
});
on digging down deeper .. I've found that when I submit a form via Http request an Error with code 500 Internal Server Error appears in console for a moment (just before page reloads)
tried everything but don't know what is causing this strange behavior .. kindly help me sort it out

You can check the network tab of your browser(Preferably Chrome) to compare the request parameters that you send to the server.
If the request is too fast that you can't capture it, try placing debugger;(Or click on the in front of the line of code in the source tab) into your Javascript code to stop the execution of the code right before it reload. Then you can inspect the current state of your Javascript and also the 500 response that you received.

Related

Saving images uploaded using ImagesLoader

I am trying to wire up the ImagesLoader plugin, which allows uploading multiple images. It has a nice drag-n-drop UI but I just can't figure out how to get the images that were uploaded. I cannot find any documentation.
Link to the plugin page: ImagesLoader
Here is the javascript from the demo:
<script type="text/javascript">
// Ready
$(document).ready(function () {
// Create image loader plugin
var imagesloader = $('[data-type=imagesloader]').imagesloader({
minSelect: 3
,imagesToLoad: [{"Url":"./img/Nespresso001.jpg","Name":"Nespresso001"},{"Url":"./img/Nespresso002.jpg","Name":"Nespresso002"}]
});
//Form
$frm = $('#frm');
// Form submit
$frm.submit(function (e) {
var $form = $(this);
var files = imagesloader.data('format.imagesloader').AttachmentArray;
var il = imagesloader.data('format.imagesloader');
if (il.CheckValidity())
alert('Upload ' + files.length + ' files');
e.preventDefault();
e.stopPropagation();
});
});
The images are saved in the object "files". Here is a screen shot of the contents from the inspector:
I tried converting to json and posting, but that only generates an error.
$.ajax({
url: 'process-images.php',
type: 'POST',
data: JSON.stringify(files),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
cache: false,
error: function() {alert("ERROR");},
success: function() {alert("OK");}
});
The rest of the code works just like the demo. Looks like everything needed for the uploaded images is stored in "files". I just need to get the data back to php and I can pull it apart from there. But right now, the original submit code just dies or my addition aborts with an error.
THANKS!
I hope it is not too late to answer.
You just need to loop through the base64 encoded image object, decoding and saving each image to the disk.
// Sample code
foreach(json_decode($request->input('files')) as $file) {
$name = $file->FileName
$imagePath = storage_path('app/public/images/');
file_put_contents($imagePath.$name, base64_decode($file->Base64));
}

Unable to render inner HTML for AJAX form with Node.js

I've coded a straightforward form which submits via Mailchimp's API to a waiting list.
This works, and the form upon submission doesn't reload the page (good), and submits the request to the server to store in Mailchimp (also good).
However, I'm wanting to update the inner HTML of the form to reflect whether the form was submitted successfully or not, without reloading the page. I've followed other questions but can't get it to work.
Here's my code at present:
Form -
<form id="early-access" class="hero-form " action="early-access" method="POST">
<input type="email" name="email" placeholder="Enter your email">
<button class="cta-button" type="submit" name="button">Get early access</button>
</form>
My AJAX jQuery code -
<script type="text/javascript">
$("#early-access").submit(function(e) {
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: form.serialize(),
done: function(data)
{
alert(data);
}
});
});
</script>
EDIT: Now adding my Early Access POST code. Noting that the form successfully adds the user to my waiting list..
module.exports = (req, res) => {
const email = req.body.email;
const data = {
members: [{
email_address: email,
status: "subscribed"
}]
};
const jsonData = JSON.stringify(data);
const url = process.env.MAILCHIMPURL;
const options = {
method: "POST",
auth: process.env.MAILCHIMPAPIKEY
};
const request = https.request(url, options, function(response) {
response.on("data", function(data) {
// console.log(JSON.parse(data));
});
});
request.write(jsonData);
request.end();
};
Also for reference - my backend is Node.js, not PHP.. Not sure if that impacts things with jQuery either.
The 'alert' in the success / error call in my AJAX isn't working, neither is my console.log. There's no mention of the request in my log. If the alert was working, I'd assume that I could just use .html to update the #early-access form.. I've tried that already but no luck unfortunately.
EDIT: In my console, after perhaps 2 minutes (roughly) after successfully submitting my form I get a 'error' alert pop up, and my console shows a 'Failed to load resource: The network connection was lost' error.
If anyone could advise, that'd be appreciated!

JavaScript Using FormData and jQuery's ajax for uploading files returns error 500 when no file is selected on iOS

I'm using FormData and jQuery's ajax for uploading files in form.
Everything works fine except when there's no file selected on iOS, then I get error 500 from PHP script.
On PC and Android it works fine if file is or isn't selected, but on iOS it works only if file is selected (it is not required to select file).
I am using latest iOS 11.4.1.
This is my code that's called when the form is submitted:
var form = this;
var data = new FormData(form);
var options = {
url: $(form).attr('action'),
data: data,
type: $(form).attr('method'),
cache: false,
contentType: false,
processData: false,
complete: function(r){
if(r.status == 200){
var response = r.responseJSON;
showErrors(form, response.errors);
$.each(response.actions, handleAction.bind(form));
}else{
showErrors(form, ['Vyskytla sa neočkávaná chyba, skúste znova neskôr']);
}
}
};
if(data.fake){
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();
}
$.ajax(options);
There was a part of code that printed the response from server and this was the response:
{"readyState":4,"responseText":"\n\n\n\n
Internal Server Error
\n
The server encountered an internal error or\nmisconfiguration and was unable to complete\nyour request.
\n
Please contact the server administrator at \n ssl#atlantis.sk to inform them of the time this error occurred,\n and the actions you performed just before this error.
\n
More information about this error may be available\nin the server error log.
\n\n","status":500,"statusText":"Internal Server Error"}
I finally found the solution to my problem, it was not on the server side.
Looks like FormData puts array of one empty File object on iOS into data variable and server cannot handle that.
I edited JS to this:
var data = new FormData(form);
$.each($(form).find('input[type="file"]'), function(){
var name = $(this).attr('name');
var files = $(this).prop('files');
if(files.length == 0){
data.set(name, null);
}
});

Post [object%20HTMLInputElement] 404 not found on $.ajax submit

I am having a slight issue trying to implement smoothState.js (https://github.com/miguel-perez/smoothState.js) with my JSP backend.
I get this error when I try to submit the form for the first time. The second time I press submit it goes through, I have no idea what is the cause of it but found a possible clue.
POST http://localhost:8080/internal/inquiry/[object%20HTMLInputElement] 404 (Not Found)
It only happens on the forms that have a hidden input with name="action". For example if I have this in my form:
<input type="hidden" name="action" value="<%=Inquiry.CREATE_ACTION_DESCRIPTION_DATA%>" />
This is the code for my submit.
$(document).ready(function(){
$('#descriptionData').parsley().on('form:success', function() {
var $form = $("#descriptionData");
var action = "<%=Inquiry.CREATE_ACTION_DESCRIPTION_DATA%>";
var formUrl = '/inquiry.do?action=' + action + '&ajax=1';
$form.submit(function (ev) {
$.ajax({
type : "POST",
url : formUrl,
data : $form.serializeArray(),
async : true,
success : function(data) {
var smoothState = $('#main-cont').smoothState().data('smoothState');
smoothState.load(data.redirectPage);
}
});
ev.preventDefault();
});
});
});
Any help would be appreciated.
EDIT: Additional photos
Response on first submit
Response on second submit
it would be great to see some jsp code, but now my guess is that if #descriptionData is actual from, then you'd better be using just $form.serialize() to send data

How can I send input file without form tag?

I am trying to send file to server with HTML and JavaScript. The scenario like below :
user clicks some button and it shows a div pop up.
user inputs file with <input type='file'>.
user presses button.
send data to server and div pop up closes.
Note that all of these actions happen in one page. Only div pop up can be open and closed.
At first, I was trying to send data with a <form> tag, and it works fine. The problem is when I submit the form it changes the page.
So what I am trying to do is sending file data without using a form tag. I have searched web, it looks somehow impossible. Is there any alternative way to send file data in div pop up?
Thanks :D
Have you considered doing it via JQuery?
You can post the values like this without a refresh:
$('#button').on('click', function(){
$.post('/url/to/your/function', {'post': value}, function(data){
if(data !== 0) {
}
}, "json");
});
You can find more info here
Edit:
It's not possible to upload files with jQuery $.post, neverthless, with the file API and XMLHttpRequest, it's perfectly possible to upload a file in AJAX, and you can even know how much data have been uploaded yet…
$('input').change(function()
{
var fileInput = document.querySelector('#file');
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload/');
xhr.upload.onprogress = function(e)
{
/*
* values that indicate the progression
* e.loaded
* e.total
*/
};
xhr.onload = function()
{
alert('upload complete');
};
// upload success
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0))
{
// if your server sends a message on upload sucess,
// get it with xhr.responseText
alert(xhr.responseText);
}
var form = new FormData();
form.append('title', this.files[0].name);
form.append('pict', fileInput.files[0]);
xhr.send(form);
}
More info here
I found a trick. It works, but I am not sure it is good way or not.
As you recommended, I use jQuery and ajax.
function sendUpgradeReq(id){
var url = '/api/update.json';
var form = $("#upgradeFrm");
var data = new FormData(form[0]);
$.ajax({
type : 'post',
dataType : 'json',
url : url,
data : data,
enctype : "multipart/form-data",
cache : false,
contentType : false,
processData : false,
success : function(data) {
alert('Success!');
$('#applyPop').css('display', 'none');
},
complete : function(data) {
},
error : function(data, status, error) {
alert('Fail! :<');
e.preventDefaultEvent();
}
});
}
I thought the most important part here is new FormData(). It takes complete file information from <input type='file'>.
Thanks :D

Categories