how to upload file using ajax request with sinatra? - javascript

i'm tring to upload file using jquery ajax function with ruby-sinatra function. here is my code.
<form id="ucform" method="post" action="#" enctype="multipart/form-data">
<input type="file" id="cfile" name="cfile" onchange="prepareUpload(this.files)">
<button type="submit">Update</button>
</form>\
javascript code
var ufiles;
function prepareUpload(files)
{
ufiles = files
}
$(function(){
$('#ucform').on('submit', uploadFiles);
});
function uploadFiles(event)
{
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening
//alert(ufiles);
// Create a formdata object and add the files
var data = new FormData();
$.each(ufiles, function(key, value)
{
data.append(key, value);
});
alert(data);
$.ajax({
url: '/upload_cfiles',
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function(data, textStatus, jqXHR)
{
alert(data);
}
});
}
sinatra function
post '/upload_cfiles' do
begin
File.open('applications/QOS/conf/' + params['cfile'][:filename], "w") do |f|
f.write(params['cfile'][:tempfile].read)
end
return "The file was successfully uploaded!"
rescue Exception => e
return e.message
end
end
above code return bellow error
ERRORS: parsererror
undefined method `[]' for nil:NilClass
please help me to solve this error

It's a safe bet that params['cfile'] is nil. Have you actually logged your request parameters to ensure you are posting what you think you're posting?
Furthermore, I believe that you're trying to upload these files using JSON - you will most likely need to base64 encode the body of the file to do this.

Related

Send data and files through multi-part forms with FormData in HTML using ajax

In the below code, I'm able to transfer data but when I use the function append to transfer file and data it's not working. Can someone tell me how to transfer file from upload? Looking forward to some help
$(document).ready(function() {
var loader = '<img src="../assets/media/loader.gif" />';
$('#submit').click(function() {
confirm("Do you really want to send messages?");
$('.loading').html(loader).fadeIn();
var msg_area_cst = $('textarea[name=msg_area_cst]').val();
var num_cst = $('textarea[name=num_cst]').val();
var form_data = new FormData();
form_data = 'msg_area_cst=' + msg_area_cst + '&num_cst=' + num_cst;
form_data.append('upload', $('input[name=upload]'));
$.ajax({
url: "../server/CustomMsg.php",
type: "POST",
data: form_data,
success: function(html) {
if (html == 1) {
$('#register_form').fadeOut('slow');
$('.loading').fadeOut();
$('.message').html('Successfully Sent ! ').fadeIn('slow');
} else
alert('Sorry, unexpected error. Please try again later.');
}
});
});
});
The problem is because you correctly declare a FormData object, but then in the next line overwrite it immediately with a string.
You need to append() all data to the FormData object. In addition you need to provide the file data to the append() method, not the jQuery object referencing the input type="file" control.
var form_data = new FormData();
form_data.append('msg_area_cst', msg_area_cst);
form_data.append('num_cst', num_cst);
form_data.append('upload', $('input[name=upload]')[0].files[0]);
That being said, you can make this much more simple if the controls you're reading the values from are contained in a form element. Then you can use the submit event of that form and pass a reference to it to the FormData constructor.
Also you don't do anything with the result of the confirm() I assume you want to stop the form submission if Cancel is clicked, which the above example now does using preventDefault().
Finally, using html == 1 is very unreliable. Firstly html will be a string so relying on implicit type coercion to an integer is not ideal. Also, returning a plain text response can cause issues if there's any whitespace included. I'd strongly suggest you change your server side logic to return a serialised format, such as JSON, and use a boolean value for a 'success' flag.
With all that said, try this:
$('#yourForm').on('submit', function(e) {
if (!confirm("Do you really want to send messages?")) {
e.preventDefault();
}
$('.loading').html(loader).fadeIn();
$.ajax({
url: "../server/CustomMsg.php",
type: "POST",
data: new FormData(this),
success: function(html) {
if (html.trim() === "1") {
$('#register_form').fadeOut('slow');
$('.loading').fadeOut();
$('.message').html('Successfully Sent ! ').fadeIn('slow');
} else
alert('Sorry, unexpected error. Please try again later.');
}
}
});
});
Try this ajax code
$.ajax({
url: "../server/CustomMsg.php",
type: "POST",
data: form_data,
contentType: false,
cache: false,
processData:false,
async: true,
success: function(html) {
if (html == 1) {
$('#register_form').fadeOut('slow');
$('.loading').fadeOut();
$('.message').html('Successfully Sent ! ').fadeIn('slow');
} else
alert('Sorry, unexpected error. Please try again later.');
}
});

How can i post data and file by using ajax on event onclick

HTML here.
<form id="myForm">
<input type="text" name="name">
<input type="file" name="userImage">
<button onclick="post('./example.php')" type="button">Save</button>
</form>
Now i want to post it by using post() function
Java-script:
Function post(url){
$.ajax({
url:url,
type: 'POST',
data: $("#myform").serialize(),
success: function (data) {
alert("successfully posted.");
}
});
}
But not serialized file
My advice is: try to have apart html and js defining the event callback on "attacheventlistener" function or "on" jquery's function (this way is easier).
Your problem is that you are passing the string "url" when you need pass a valid url, so write the url directly on ajax url field or define a data attribute on your form tag, e.g. data-url="http://whatever", and catch this value from the event.
If you use jquery's "on" function is extremly easy, you could to get it data's value via jquery's "data" function over "this" var.
Something like ...
$("#myForm").on("click",
function() {
post(this.data("url"));
});
But probably you do not need url being a var.
If I understand correctly, the problem is that nothing is being posted.
The thing is is that you are trying to do a file upload via ajax, this is not wrong but it needs to be done differently shown here:
jQuery Ajax File Upload
You can add extra data with form data
use serializeArray and add the additional data:
var data = $('#myForm').serializeArray();
data.push({name: 'tienn2t', value: 'love'});
$.ajax({
type: "POST",
url: "your url.php",
data: data,
dataType: "json",
success: function(data) {
//var obj = jQuery.parseJSON(data); if the dataType is not specified as json uncomment this
// do what ever you want with the server response
},
error: function() {
alert('error handing here');
});
First of all i need to say that, if you want to upload file, i mean if your form have file input then add the form attribute enctype="multipart/form-data" according to RFC-7578. you can also see the uses http://www.w3schools.com/tags/att_form_enctype.asp.
Then move to the html part again. Suppose you have a form input like
<form action="some_domain/example.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="fileId"/>
<input type="text" name="firstName" id="name">
<button onclick="post('some_domain/example.php')" type="button">Save</button>
</form>
Now post the file data using ajax:
function post(url){
$.ajax({
url:url,
type: 'POST',
processData:false,
contentType:false,
data: $('#fileId')[0].files[0],
success: function (data) {
alert("successfully posted.");
}
});
}
I think this should be worked fine.
UPDATE:
if you want to post text data as well then you should use FormData object.
function post(url){
var formData = new FormData();
var files = document.getElementById("fileId").files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
formData.append('files[]', file, file.name);
}
formData.append('firstName',$('#name').val());
$.ajax({
url:url,
type: 'POST',
processData:false,
contentType:false,
data: formData,
success: function (data) {
alert("successfully posted.");
}
});
}

Upload Avatar To Server Using AJAX

I have looked into the best way to do this and keep getting conflicting information and advice on the various demonstrations.
My code is as follows...
html
<img src="http://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?s=265&d=identicon&r=PG" style="border: thin solid #999999;"/>
<p>Change<span class="pull-right">Powered by Gravatar</span></p>
<input type="file" name="avatar-uploader" id="avatar-uploader" style="display: none;" />
javascript
$('input[type=file]').on('change', function(){
$.ajax({
url: "/ajax/upload-new-avatar.ajax.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data) // A function to be called if request succeeds
{
alert("Success");
}
});
});
PHP: /ajax/upload-new-avatar.ajax.php
error_reporting(E_ALL);
ini_set('display_errors', 1);
session_start();
$sourcePath = $_FILES['avatar-uploader']['tmp_name']; // Storing source path of the file in a variable
$targetPath = "".$_FILES['avatar-uploader']['name']; // Target path where file is to be stored
move_uploaded_file($sourcePath,$targetPath) ; // Moving Uploaded file
I'm sure there is something simple that I am missing here and i'm going to feel pretty stupid afterwards but could someone explain to me why the image isn't being uploaded to the server and saved in the AJAX directory for further processing.
What I need it to do is when the user clicks on the "change" hyperlink below the image it opens a file upload dialog (working), once an image has been selected it automatically uploads to the server over an AJAX connection (possibly working, logging shows the PHP file is being triggered), and then the image file needs to be saved in the AJAX directory to be further processed later in the code for it to be uploaded to the avatar service.
Thanks in advance.
Have managed to get it working...
Here is my amended code...
Javascript
$('input[type=file]').on('change', function(event){
files = event.target.files;
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening
$("#avatar-status").text("Loading new avatar...");
$("#avatar").css("opacity", "0.4");
$("#avatar").css("filter", "alpha(opacity=40);");
//Create a formdata object and add the files
var data = new FormData();
$.each(files, function(key, value) {
data.append(key, value);
});
$.ajax({
url: '/ajax/upload-new-avatar.ajax.php?files',
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function(data, textStatus, jqXHR) {
if(typeof data.error === 'undefined') {
//Success so call function to process the form
//submitForm(event, data);
$("#avatar-status").text("Powered by Gravatar");
$("#avatar").css("opacity", "");
$("#avatar").css("filter", "");
} else {
//Handle errors here
alert('ERRORS: ' + textStatus);
}
},
error: function(jqXHR, textStatus, errorThrown) {
//Handle errors here
alert('ERRORS: ' + textStatus);
}
});
});
PHP
session_start();
require_once("../libraries/logging.lib.php");
new LogEntry("AJAX Upload Started - UploadNewAvatar", Log::DEBUG, "AvatarUpload");
sleep(3);
$data = array();
if(isset($_GET['files'])) {
$error = false;
$files = array();
$uploaddir = '../tmp/';
foreach($_FILES as $file) {
if(move_uploaded_file($file['tmp_name'], $uploaddir .basename($file['name']))) {
$files[] = $uploaddir .$file['name'];
new LogEntry("UploadNewAvatar - Upload Successful", Log::DEBUG, "AvatarUpload");
} else {
$error = true;
new LogEntry("UploadNewAvatar - Errors Occured", Log::ERROR, "AvatarUpload");
}
}
$data = ($error) ? array('error' => 'There was an error uploading your files') : array('files' => $files);
} else {
$data = array('success' => 'Form was submitted', 'formData' => $_POST);
new LogEntry("UploadNewAvatar - Form was submitted successfully", Log::DEBUG, "AvatarUpload");
}
echo json_encode($data);
HTML
<img id="avatar" src="http://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?s=265&d=identicon&r=PG" style="border: thin solid #999999;"/>
<p>Change<span id="avatar-status" class="pull-right">Powered by Gravatar</span></p>
<input type="file" name="upfile" id="upfile" style="display: none;" />

Ajax form within eModal does not submit

I use eModal to call for a modal remotely via ajax. Although within the modal I have a form and the javascript code does not listen to it and thus it doesn't post. My codes are as follows;
eModal and Ajax for the form;
$(document).ready(function() {
// process the PROJECT UPDATE form
$('#proj-edit').submit(function(event) {
// get the form data
var formData = {
'projID' : $('input[name=projID]').val(),
'projname' : $('input[name=projname]').val(),
'projstart' : $('input[name=projstart]').val(),
'projend' : $('input[name=projend]').val(),
'projhotel' : $('input[name=projhotel]').val(),
'projcity' : $('input[name=projcity]').val(),
'projstatus' : $('#projstatus').val()
};
if (formData.projname == '' ||
formData.projstart == '' ||
formData.projend == '' ||
formData.projhotel == '' ||
formData.projcity == '') {
return false;
}
// process the form
$.ajax({
type : 'POST',
url : 'inc/prjedit.ajax.php',
data : formData,
dataType : 'json',
encode : true
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
// here we will handle errors and validation messages
if ( ! data.success) {
} else {
$('#proj-edit').trigger('reset');
swal("Success!", "Edit success!", "success");
}
})
// using the fail promise callback
.fail(function(data) {
// show any errors
console.log(data);
});
event.preventDefault();
});
$('button[id=demo]').click(function() {
var value = $(this).val();
ajaxDemo(value)
});
function ajaxDemo(value) {
var title = 'Ajax modal';
var params = {
size: eModal.size.lg,
title: title,
type: 'GET',
url: 'inc/demo.ajax.php?pID='+ value
};
eModal.setEModalOptions({
loadingHtml: '<div class="text-center"><span class="fa fa-circle-o-notch fa-spin fa-5x text-primary"></span></div>',
});
return eModal
.ajax(params);
}
});
The modal content is rather simple;
<form class="form" method="POST" action="" id="proj-edit" name="proj-edit">
// the input fields are here. Although since it is too long, I did not include them in here.
<button type="submit" class="btn btn-info" name="update-prj">Register</button>
</form>
I should note that the JavaScript code is in a different document named magic.js, the modal works although it does not submit the form. What am I missing here or what am I doing wrong?
The console log has this to say about all this;
(When eModal opens ->) XHR finished loading: GET "http://localhost/parantez/inc/demo.ajax.php?pID=301".k.cors.a.crossDomain.send # jQuery-2.1.4.min.js:4n.extend.ajax # jQuery-2.1.4.min.js:4n.fn.load # jQuery-2.1.4.min.js:4ajax # eModal.js:336ajaxDemo # magic.js:270(anonymous function) # magic.js:253n.event.dispatch # jQuery-2.1.4.min.js:3r.handle # jQuery-2.1.4.min.js:3
(When form is submitted ->) Navigated to http://localhost/
This issue has now been solved thanks to this post. Thank you very much for taking your time to answer, I highly appreciate your input. Kudos to all of you.
you are passing javascript object to php which is not valid in ajax request
use JSON.stringify() to convert json object into string and inside php use json_decode function to make object of json ...
like this
$.ajax({
type : 'POST',
url : 'inc/prjedit.ajax.php',
data : JSON.stringify(formData),
dataType : 'json',
encode : true
})
if you don't want to send json data then use
formData to send data with ajax same as from submission like that
data = new FormData();
data.append('projID', $('input[name=projID]').val());
do this for all and then simply pass data to ajax function like this
$.ajax({
url: 'http://example.com/script.php',
data: data,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
ok hope this will help ...

Javascript pass input file to PHP

I don't want to upload a file using Javascript, I just want to pass by Ajax the file to a PHP file, and in the PHP make the validations I want, plus use the move_uploaded_file function. Is it possible?
$('#the_button').on("click", function(){
var image = $('#image').val() == "" ? null : $('#image').files;
$.ajax({
type: "POST",
url: "insert.php?type=image",
data: image,
enctype: 'multipart/form-data',
success: function(data) {
alert(data);
}
});
}
This returns 'undefined' for the #image.
$('#image').files[0] also returns undefined.
$('#image')[0].files returns [object FileList] -> is it correct?
try this plugin
http://blueimp.github.io/jQuery-File-Upload/
$('#fileupload').fileupload({
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
});
}
});
You can not upload files via AJAX.
Usual way is to set the target of your form to a hidden iframe.
Something like this.
<form target="myHiddenIframe" method="post" enctype="multipart/form-data">
//your form elements here.
</form>
<iframe name="myHiddenIframe" id="myHiddenIframe" style="display: none;" />
Submit the form to achieve what you want.

Categories