Can't upload multiple files using ajax - javascript

First of all this might be a silly question as there are many topics available on this but seriously I am not being able to get it straight and understand how to make it work.
WHAT I AM TRYING TO DO
I am trying to upload multiple files using AJAX and PHP.
PROBLEM
I cant figure out how to pass the data to the PHP script using AJAX.
I don't want to use a form and a submit button for uploading.
Tried using a form and submitting it using jQuery still couldn't make
it.
HTML
<div id="content">
<div id="heading">Upload your files seamlessly</div>
<a href="#"><div id="upload" class="button" title="Upload your files"><i class="fa fa-cloud-upload fa-align-center" aria-hidden="true"></i>
</div></a>
<a href="view.php"><div id="view" class="button" title="View all files on my cloud"><i class="fa fa-eye fa-align-center" aria-hidden="true"></i>
</div></a>
</div>
<form id="fileupload" method="POST" enctype="multipart/form-data">
<input type="file" multiple name="uploadfile[]" id="uploadfile" />
</form>
JS
<script type="text/javascript">
$(document).ready(function(){
$('#upload').click(function(){
$('input[type=file]').click();
return false;
});
$("#uploadfile").change(function(){
//submit the form here
$('#fileupload').submit();
});
});
</script>
PHP
<?php
if(isset($_FILES['uploadfile'])){
$errors= array();
foreach($_FILES['uploadfile']['tmp_name'] as $key => $tmp_name ){
$file_name = $key.$_FILES['uploadfile']['name'][$key];
$file_size =$_FILES['uploadfile']['size'][$key];
$file_tmp =$_FILES['uploadfile']['tmp_name'][$key];
$file_type=$_FILES['uploadfile']['type'][$key];
if($file_size > 2097152){
$errors[]='File size must be less than 2 MB';
}
//$query="INSERT into upload_data (`USER_ID`,`FILE_NAME`,`FILE_SIZE`,`FILE_TYPE`) VALUES('$user_id','$file_name','$file_size','$file_type'); ";
$desired_dir="storage";
if(empty($errors)==true){
if(is_dir($desired_dir)==false){
mkdir("$desired_dir", 0700); // Create directory if it does not exist
}
if(is_dir("$desired_dir/".$file_name)==false){
move_uploaded_file($file_tmp,"$desired_dir/".$file_name);
}
else{ // rename the file if another one exist
$new_dir="$desired_dir/".$file_name.time();
rename($file_tmp,$new_dir) ;
}
//mysql_query($query);
}
else{
print_r($errors);
}
}
if(empty($error)){
echo "Success";
}
}
?>
Any help would be appreciated.

This is a very simple example of what you want to do.
HTML
Wrap your inputs within a form. Why? Because it is the easiest way to do it.
<form action="process.php" method="post">
<input type="file" multiple name="uploadfile[]">
<input type="submit" value="Upload">
</form>
JavaScript
Attach an onsubmit event handler to your form. Use $.ajax() to send a POST request.
Pass your form element i.e. this into the constructor of a FormData object and use it as your data when you send the request as shown below. You need to make sure that you set processData and contentType as false also for this to work.
$(function () {
$('form').on('submit', function (e) {
e.preventDefault();
// send request
$.ajax({
url: this.action,
type: this.method,
data: new FormData(this), // important
processData: false, // important
contentType: false, // important
success: function (res) {
alert(res);
}
});
});
});
PHP (process.php)
Let's clean up your PHP.
<?php
// always a good idea to turn on errors during development
error_reporting(E_ALL);
ini_set('display_errors', 1);
$dir = './storage';
$errors = [];
if (isset($_FILES['uploadfile'])) {
$files = $_FILES['uploadfile'];
// create directory if it does not exist
!is_dir($dir) && mkdir($dir, 0700);
// validate & upload files
foreach (array_keys($files['tmp_name']) as $key) {
$file = [
'name' => $files['name'][$key],
'size' => $files['size'][$key],
'tmp_name' => $files['tmp_name'][$key],
'type' => $files['type'][$key],
'error' => $files['error'][$key]
];
// skip if no file was given
if ($file['error'] === UPLOAD_ERR_NO_FILE) {
continue;
}
// get file extension
$file['ext'] = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
// generate a unique name (!)
$file['name'] = uniqid() . '.' . $file['ext'];
// validate
if (!file_exists($file['tmp_name']) ||
!is_uploaded_file($file['tmp_name']) ||
$file['error'] !== UPLOAD_ERR_OK) {
$errors[$key] = 'An unexpected error has occurred.';
} elseif ($file['size'] > 2097152) {
$errors[$key] = 'File size must be less than 2 MB';
// upload file
} elseif (!move_uploaded_file($file['tmp_name'], $dir . '/' . $file['name'])) {
$errors[$key] = 'File could not be uploaded.';
}
}
}
if ($errors) {
print_r($errors);
} else {
echo 'no errors';
}
?>
(!) Do keep in mind that uniqid() is actually not unique.

Related

Jquery & Ajax -> File upload not possible

I got totally lost.
Ive tried to make some Image Upload function in PHP and everything works fine. Because i dont want the whole Page to reload, when uploading a File i wanted to use AJAX with Jquery, to send the Form Content (Image) via POST to a file like upload.php with an hidden ajax request.
No matter what i try its impossible to send anything with formData(). I copied & pasted several Sample Codes, tried changing the Code, nothing happens when i use formData().
A normal request with Jquery / Ajax, using POST works fine.
Here ist the Sample of my last used Code..
Could my XamPP has been misconfigured, or what could cause that really not one of the Scripts from google, tutorial pages etc works?
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript" src="jquery.min.js"></script>
<form id="Test" action="" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
</form>
<button id="Knopf">Knopf</button>
<div id="Disp">fghfgh</div>
</body>
<script>
$(document).ready(function(){
$("#Knopf").click(function(){
var formData = new FormData(Test);
$.ajax({
url : "uploadtest2.php",
type : "POST",
data : formData,
cache : false,
contentType : false,
processType : false,
success : function() {
$("#Disp").html(result);
}
});
});
});
</script>
</html>
<?php
$target_dir = "Media/uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "File is not an image.";
$uploadOk = 0;
}
}
// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "The file ". htmlspecialchars( basename( $_FILES["fileToUpload"]["name"])). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
?>
The problem is this:
if(isset($_POST["submit"])) {
There's no element named submit in the form, so this check fails. Even if you had a submit button in the form, it wouldn't be included in formData, because buttons are only automatically included in POST data when they trigger normal form submission.
You can add that to formData.
var formData = new FormData(Test);
formData.set("submit", "1");
Or you could change your test to
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
Please see: https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
You must use a Form Element:
An HTML <form> element — when specified, the FormData object will be populated with the form's current keys/values using the name property of each element for the keys and their submitted value for the values. It will also encode file input content.
Consider the following example.
$(function() {
$("#Test").submit(function(e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: "uploadtest2.php",
type: "POST",
data: formData,
cache: false,
contentType: false,
processType: false,
success: function(result) {
$("#Disp").html(result);
}
});
});
$("#Knopf").click(function() {
$("#Test").submit();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="Test" action="" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="fileToUpload" id="fileToUpload" />
</form>
<button id="Knopf" type="submit">Knopf</button>
<div id="Disp">fghfgh</div>
It is better to bind to the submit callback. This way, if the User submits the form or clicks Submit, the callback is triggered. We need to .preventDefault() on the Event to ensure the Form doesn't post or submit the data. Now we can then perform the AJAX call without the page being refreshed.
In your success callback, you must pass in a variable to be used for the returned data. Otherwise result will be undefined.
With the proper FormData, there should be no issue uploading. this in the callback refers to the Form Element itself.
Consider updating your PHP as well:
if(isset($_POST["submit"])) {
Change this to:
if(isset($_POST["fileToUpload"])) {

Multiple images upload using javascript, PHP, MySQl

Here I am doing a Hybrid Android app conversion. My page is HTML page. I need to upload multiple images using Javascript only. In my page I can't use PHP if(isset($_POST['submit'])) function because it's a HTML page. And also I can't use <form action='upload.php' method='POST'>, because it redirect to that PHP page. So I can't be in a same page.
<form method="POST" action="" id="proinsert" name="proinsert" enctype="multipart/form-data">
<input type="file" name="photo" id="photo" class="form-control">
<button id="submit" name="submit" class="btn btn-primary margintop">Submit</button>
</form>
and my PHP page
foreach($_FILES['photos']['name'] as $file){
$message .= "Attachments:" .$file['filename'];
}
Your question is very broad. However, I'll do my best to answer it:
You have 3 logical layers to your problem here:
The HTML that creates the user interface
The Javascript - that handles processing and sending your images (or any file) to another place.
Your PHP code, which will accept your images and process/save them to your server.
A brief overview of how to approach the solution:
Build a form in HTML with a file upload field.
<form method="post" enctype="multipart/form-data">
<input type="file" name="files[]" multiple>
<input type="submit" value="Upload File" name="submit">
</form>
In your HTML file, write or include Javascript that will serialise the form data, and POST it to your PHP file.
<script type="text/javascript">
const url = 'process.php';
const form = document.querySelector('form');
form.addEventListener('submit', e => {
e.preventDefault();
const files = document.querySelector('[type=file]').files;
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
let file = files[i];
formData.append('files[]', file);
}
// Uses browser's built in Fetch API - you can replace this with jQuery or whatever you choose.
fetch(url, {
method: 'POST',
body: formData
}).then(response => {
console.log(response);
});
});
</script>
Write the logic into a new PHP file (called process.php) to handle the form data (images) as appropriate.
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['files'])) {
$errors = [];
$path = 'uploads/';
$extensions = ['jpg', 'jpeg', 'png', 'gif'];
$all_files = count($_FILES['files']['tmp_name']);
$fileNames = [];
for ($i = 0; $i < $all_files; $i++) {
$file_name = $_FILES['files']['name'][$i];
$file_tmp = $_FILES['files']['tmp_name'][$i];
$file_type = $_FILES['files']['type'][$i];
$file_size = $_FILES['files']['size'][$i];
$file_ext = strtolower(end(explode('.', $_FILES['files']['name'][$i])));
$fileNames[] = $file_name;
$file = $path . $file_name;
if (!in_array($file_ext, $extensions)) {
$errors[] = 'Extension not allowed: ' . $file_name . ' ' . $file_type;
}
if ($file_size > 2097152) {
$errors[] = 'File size exceeds limit: ' . $file_name . ' ' . $file_type;
}
if (empty($errors)) {
move_uploaded_file($file_tmp, $file);
}
}
if ($errors) {
print_r($errors);
} else {
print_r(json_encode(['file_names' => $fileNames]));
}
}
}
For speed - the example code in this solution was taken from https://www.taniarascia.com/how-to-upload-files-to-a-server-with-plain-javascript-and-php/
For other examples - you could check out StackOverflow's other questions. Here's a similar one to yours: uploading image using javascript

jQuery Ajax form two submit button in one form

I have 2 button in one form. When I click the first or second button, both write example an alert, but the Ajax request doesn't run. I need a form, because i would like to upload images. I don't know what is the problem.
page.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Ajax two submit in one form</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<form id="animal-upload" method="post" enctype="multipart/form-data">
<span>Name:</span>
<input type="text" name="animalname" id="animalname">
<span>Image:</span>
<input type="file" name="imagefile" id="imagefile">
<button type="submit" name="publish" id="publish">Publish</button>
<button type="submit" name="save" id="save">Save</button>
</form>
<script>
$(document).ready(function() {
$('#animal-upload').on('submit', function() {
return false;
});
$('#publish').click(function() {
alert("Test");
});
$('#save').click(function(e) {
e.preventDefault();
$.ajax({
url: "animal-upload.php",
type: "POST",
data: new FormData(this),
contentType: false,
processData: false,
success: function(data) {
alert(data);
}
});
});
});
</script>
</body>
</html>
animal-upload.php
<?php
$connect = mysqli_connect("localhost", "root", "", "test");
mysqli_set_charset($connect,"utf8");
$status = '';
$animalname = $connect->real_escape_string($_POST["animalname"]);
if ($_FILES['imagefile']['name'] != '') {
$extension = end(explode(".", $_FILES['imagefile']['name']));
$allowed_type = array("jpg", "jpeg", "png");
if (in_array($extension, $allowed_type)) {
$new_name = rand() . "." . $extension;
$path = "animals/" . $new_name;
if (move_uploaded_file($_FILES['imagefile']['tmp_name'], $path)) {
mysqli_query($connect, "INSERT INTO animals (animalname,image) VALUES ('".$animalname."','".$path."')");
$status = 'Successful!';
}
} else {
$status = 'This is not image file!';
}
} else {
$status = 'Please select image!';
}
echo $status;
?>
After trial and errors I found the script work if you change this line :
data: new FormData($("#animal-upload")[0]),
Because that selects the form object.
You may consider some security tips :
Don't divulge your password in public
Don't let your database users connect without passwords
Make a user with strict minimum privileges just for the purpose to connect to your database from PHP scripts (it's called the principle of least privileges)
Rename your uploaded file
For the file upload to work :
Make sure you have the right permissions on the directory pointed by
upload_tmp_dir in php.ini file
You may need to check that your file size doesn't exceed the memmory_limit directive too
good luck,

how to request a single file as object

I just start to learn javascirpt, php about 2 days. The problem I face is I already have a x.dcm file under server root, and I already known that path(e.g. http://localhost:8888/....)
My question is how can I simply grab that file from server to use, maybe something like:
var file= 'http://localhost:8888/....'; ////file is not an object
I ask this question because I already known how to use input method:
<input type="file" name="file" id="file">
<script>
$('#file').on('change',function(e){
var file = e.target.file; ///file is an object
});
</script>
but that is not what I want, what I want is to use an existed file rather than input.
So the whole thing is that:
<form id="input" method="post" enctype="multipart/form-data">
<input type="file" id="fileToUpload" name="fileToUpload">
</form>
I firstly make a input to upload some file,then in script
<script>
$("form#input").submit(function(){
var formData = new FormData($(this)[0]);
$.ajax({
url: 'segmentation.php',
type: 'POST',
data: formData,
async: false,
success: function (html) {
$('#segbound').html(html);
},
cache: false,
contentType: false,
processData: false
});
return false;
});
</script>
I sent this file(e.g image.dcm) to do something( run a exec) on the server side, then it generates another image(imgproc.dcm) in an expected path(http://localhost:8888/....), and then the next thing is that I what that processed image display on the screen. To do that I need to use a js called cornerstone, and the function in it imageLoader.fileManager.get(file)
which file is that one I what to display.
When I select from input using var file = e.target.file; as I mentioned above, it works perfect, then I check the file type it is a [file object].
But when I want to simply display that 'imgproc.dcm' by using var file= 'http://localhost:8888/....'; the file type is not an object which comes out my question, how can I simply grab that known path image to use as an object.
Or, to improve that, it is possible to get the return (generated imgproc.dcm) directly after it process on server side, and then to use that return(maybe give it an id...do not know) to display (call cornerstone function imageLoader.fileManager.get(file))
On server side, it looks like:
<?php
$target_dir = "/Applications/MAMP/htdocs/dicomread/temp/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
if (file_exists($target_file)) {
echo "file has already been uploaded.";
$uploadOk = 0;
}
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
} else {
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $target_file)) {
echo "The file ". basename( $_FILES['fileToUpload']['name']). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
$cmd = "/Applications/MAMP/htdocs/dicomread/abc 2>&1";
$Output_fileName = "imgproc.dcm";//$_FILES['fileToUpload']['name'];
exec("$cmd $target_file $Output_fileName);
echo "<br/>done";
?>
Any help would be appreciated.
Use fopen with URL to the file:
$file = fopen("http://localhost:8888/x.dcm", "r");
Refer to this for fopen: http://php.net/manual/en/function.fopen.php

Return new file name from mini-upload-form

I'm using Mini AJAX Upload Form to upload files to a server. I modified the upload code to add a time stamp the the end of the file. How can I return the new name of the file (with the time stamp) to the client for later use?
date_default_timezone_set('America/New_York');
$date = date('.YmdHis');
// A list of permitted file extensions
$allowed = array('sqlite', 'db', 'db3');
if(isset($_FILES['upl']) && $_FILES['upl']['error'] == 0){
$extension = pathinfo($_FILES['upl']['name'], PATHINFO_EXTENSION);
if(!in_array(strtolower($extension), $allowed)){
echo '{"status":"error"}';
exit;
}
$file = '/var/www/html/uploads/'.$_FILES['upl']['name'].$date;
if(move_uploaded_file($_FILES['upl']['tmp_name'], $file)){
echo '{"status":"success"}';
exit;
}
}
echo '{"status":"error"}';
exit;
JS:
$(function(){
$('#drop a').click(function(){
// Simulate a click on the file input button
// to show the file browser dialog
$(this).parent().find('input').click();
});
// Initialize the jQuery File Upload plugin
$('#upload').fileupload({
url: 'includes/php/upload.php',
// This element will accept file drag/drop uploading
dropZone: $('#drop'),
});
// Prevent the default action when a file is dropped on the window
$(document).on('drop dragover', function (e) {
e.preventDefault();
});
});
HTML snippet:
<div class="row">
<div class="col-lg-12 text-center">
<form id="upload" method="post" enctype="multipart/form-data">
<div id="drop">
<p>Drop Database Here</p>
<a>Browse</a>
<input type="file" name="upl" multiple/>
</div>
</form>
</div>
</div>
NOTE: Mini AJAX Upload Form uses jQuery-File-Upload
you can use the done call back to get he file name after upload it, of course you need to write it back to your ajax in you php script
done: function (e, data) {
$("tr:has(td)").remove();
$.each(data.result, function (index, file) {
$("#uploaded-files").append(
$('<tr/>')
.append($('<td/>').text(file.fileName))
.append($('<td/>').text(file.fileSize))
.append($('<td/>').text(file.fileType))
.append($('<td/>').html("<a href='upload?f="+index+"'>Click</a>"))
.append($('<td/>').text("#"+file.twitter))
)//end $("#uploaded-files").append()
});
},
also this example is java example but they do similar thing to what you do
http://hmkcode.com/java-servlet-jquery-file-upload/

Categories

Resources