Trying to upload images without refreshing page with javascript, not working - javascript

I am trying to upload images to my server via an html-form without refreshing the page. My problem is the files arent getting uploaded and I cant figure out why.
Javascript code:
function uploadFiles(event) {
var fileSelect = document.getElementById('file');
var files = fileSelect.files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (!file.type.match('image.*')) {
alert("File: " + file.name + " is not an image and will not be uploaded.");
continue;
}
formData.append('images[]', file, file.name);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '../htdocs/Php/upload_file.php', true);
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
alert('files uploaded');
} else {
alert('An error occurred!');
}
};
xhr.send(formData);
}
HTML code:
<form action="../htdocs/Php/upload_file.php" method="post" enctype="multipart/form-data">
<input type="file" name="images[]" id="file" onchange="uploadFiles()" multiple required />
</form>
PHP code:
$numberOfFiles = count($_FILES['images']['name']);
for($id = 0; $id < $numberOfFiles; $id++)
{
if (!file_exists("../UploadedImages/" . $_FILES["images"]["name"][$id])) {
move_uploaded_file($_FILES["images"]["name"][$id], "../UploadedImages/" . $_FILES["images"]["name"][$id]);
}
}

Looks like your JavaScript is correct, but your PHP needs some attention. I modified your php so that it first check to see if $_FILES were passed. Then where you had some incorrect logic was in your !file_exists() statement and how you move and check the file name.
To check if a file exists, and to move the file you need to use $_FILES['images']['tmp_name']. The 'name' attribute is just the name of the file uploaded, not the physical file uploaded to the browser.
To really test your code, use firebug and look at the console. It should return a line that you can expand and look at what was posted and what was returned.
Here is an example, the following code i gave you returns this:
C:\filepath\binaries\tmp\phpDB53.tmp Was Succesuflly uploaded
C:\filepath\binaries\tmp\phpDB54.tmp Was Succesuflly uploaded
C:\filepath\binaries\tmp\phpDB55.tmp Was Succesuflly uploaded
C:\filepath\binaries\tmp\phpDB56.tmp Was Succesuflly uploaded
NOTE: Double check that the files paths are absolutely correct. When checking firebug console, the php file will also return file errors as well, given that you have php error reporting on.
//Check if files were passed through to your ajax page
if(isset($_FILES)) {
$numberOfFiles = count($_FILES['images']['name']);
for($id = 0; $id < $numberOfFiles; $id++)
{
if (file_exists($_FILES["images"]["tmp_name"][$id])) {
move_uploaded_file($_FILES["images"]["tmp_name"][$id], $_FILES["images"]["name"][$id]);
echo $_FILES["images"]["tmp_name"][$id] . " Was Succesuflly uploaded \r\n ";
} else {
echo "file didnt exists " . $_FILES["images"]["tmp_name"][$id] . "\r\n ";
}
}
} else {
//No Files were passed through
echo "no files passed through";
}
exit();
Hopefully that answers your question.

Related

Uploading large videos & Audio files to server using XMLHttpRequest

I have a form that has been working perfectly fine when it comes to uploading files and large images. For any image that is too large it gets resized using a canvas and then I append it to the form Data and it saves perfectly. However I have now been asked to allow videos and audio files to be uploaded on the same file input.
This sort of has thrown me for a bit of a loop because even shorter videos from a phone can be 50MB or more especially if the quality of the camera is good. I searched for a number of things but I can't seem to find something that already somewhat works with the submission process I have going on.
I saw I can split the file into chunks and upload it in pieces to the server, but the other unfortunate part is when I submit the file (image, pdf, mp4, mp3) I am also submitting other information, like Description (small paragraph describing the file), name of person submitting the file etc.
My current process goes a little something like this:
Person uploads file + information, I send it away using formData and new XMLHttpRequest().
On the server side I get the name, set the path and get a date for the submission. The name of the image/file gets changed to be something like 20200128200812_imageName.jpeg which helps me retrieve the image based on what time the form was submitted (database column frmSubmitted).
What I am attempting to do:
Allow a user submit a form with the ability to process video types and audio types but still process the information that is associated with the file, like name or description.
I'm afraid if I submit the video or audio file in chunks, I will be also submitting the other information as well, I might be wrong on this but all other posts I have read seem to mention making separate requests might be the only way to do this. The following code works and is how I am currently set up but I am including it for context.
html
<input type="text" id="name"/>
<textarea id="description" name="description" rows="5" cols="50" maxlength="2000"></textarea>
<input type="file" name="sFile" id="sFile" multiple />
<button onclick="submitFile();" class="btn" >submit</button>
JS
function submitFile(){
const files= document.querySelector('#sFile').files;
var formData = new FormData();
if (files.length > 0){
for (var i = 0; i < files.length; i++) {
var file= files[i];
if(checkFileExtension(file) && checkFileSize(file)){ //checks the file for images and the size of the image
image = resizeImage(file);
formData.append('images[]', image);
}else{
formData.append(file[], file);
}
}
}
/*
*getting values & error handling...
*/
//appending values
formData.append('desc', description);
formData.append('personName', name);
var postrequest = new XMLHttpRequest();
postrequest.open('post', 'include/fileProcessing.php', true);
postrequest.send(formData);
postrequest.onload = function(){
var data = JSON.parse(postrequest.responseText);
if(data.result == 'true' ){
alert('Form has been submitted!');
}
php
$date = date('YmdHis');
if (isset($_FILES['images'])) {
$errors = [];
$path = '../images/uploads/';
$extensions = ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'pdf'];
$all_files = count($_FILES['images']['tmp_name']);
for ($i = 0; $i < $all_files; $i++) {
$original_Name = $_FILES['images']['name'][$i];
$file_name = $date .'_'.$original_Name;
$file_tmp = $_FILES['images']['tmp_name'][$i];
$file_type = $_FILES['images']['type'][$i];
$file_size = $_FILES['images']['size'][$i]/1024;
$file_ext = strtolower(end(explode('.', $_FILES['images']['name'][$i])));
if (!in_array($file_ext, $extensions)) {
$errors[] = 'Image type not allowed: ' . $original_Name . ' ' . $file_type;
}
if ($file_size > 2097152) {
$errors = 'Image size too large';
}
$file = $path . $file_name;
if (empty($errors)) {
move_uploaded_file($file_tmp, $file);
}
}
if ($errors) $rtVariables['picErrors'] = $errors;
}
/**check and upload files that are not images but too long to post**/
Any help would be greatly appreciated.

I want to clear contents of file in chrome extension and the file is on server. How to do that?

I have written the below code in my js file in chrome extension.
var xhr_put = new XMLHttpRequest();
xhr_put.open('PUT',"https://something/index.php",true);
xhr_put.onreadystatechange = function()
{
console.log('File Cleared',"Yes");
}
And the below code in my PHP file.
$requestmethod = 'PUT';
if ($_REQUEST['REQUEST_METHOD'] === $requestmethod)
{
$f = #fopen("facebookmsg.txt", "w");
print "in here";
if ($f !== false) {
ftruncate($f, 0);
fclose($f);
echo "here";
}
}
But my file on server is not getting empty. I need help as to what is wrong and how do i correct it?

How to store image to folder and store the path to database using Ajax?

I am developing an application that use HTML and js for front-end and PHP for back-end. I have the following code which should have the functions that: 1, when click on the background image, user can choose photo from there phone as new background image, and use PHP to save the image on server and get the image path, store the path into database, then send new path back to front with JSON, and display the selected image as new background image. Thanks for any help.
javascript for sending and retrieve data:
function UploadImageDialog()
{
$("#newProfileImage").click();
}
function profileImageSelected(fileInput)
{
var xhr = new XMLHttpRequest();
xhr.open("POST", "UploadProfileImage.php", true);
var formData = new FormData();
formData.append("file", fileInput.files[0]);
xhr.send(formData);
xhr.onload = function() {
alert(xhr.responseText); //test the returned info from PHP.
if(xhr.responseText != ""){
$("#profileBackgroundImage").setAttribute("src", xhr.responseText);
}
else
{
alert("Your file failed to upload");
}
}
}
HTML code to call the javascript:
<div style="width:91.5vw;height:78.5vh;margin-top:10.5vh;">
<img class="backgroundImage" id="pictureSrc" src="img/Jenny.jpg" onclick="UploadImageDialog()" />
</div>
<input type="file" id="newProfileImage" style="display:none;" onchange="profileImageSelected(this)"/>
PHP code to get the path:
<?php
if(is_uploaded_file($_FILES['file']['tmp_name'])) // if user uploads file
{
if (!file_exists("./img/EventImages/" . $_FILES["file"]["name"]))
{
if (move_uploaded_file($_FILES["file"]["tmp_name"], "./img/EventImages/" . $_FILES["file"]["name"]))
{
echo "img/EventImages/" . $_FILES["file"]["name"];
}
}
else
{
echo "img/EventImages/" . $_FILES["file"]["name"];
}
}
?>
You should use some libraries like uploadify to upload files without posting form.
DEMO
I have figured that out. There was nothing wrong with the code, but I didn't set the Directory Permission correctly on the server.

How to upload base64 image resource with dropzone?

I'm trying to upload generated client side documents (images for the moment) with Dropzone.js.
// .../init.js
var myDropzone = new Dropzone("form.dropzone", {
autoProcessQueue: true
});
Once the client have finished his job, he just have to click a save button which call the save function :
// .../save.js
function save(myDocument) {
var file = {
name: 'Test',
src: myDocument,
};
console.log(myDocument);
myDropzone.addFile(file);
}
The console.log() correctly return me the content of my document
data:image/png;base64,iVBORw0KGgoAAAANS...
At this point, we can see the progress bar uploading the document in the drop zone but the upload failed.
Here is my (standart dropzone) HTML form :
<form action="/upload" enctype="multipart/form-data" method="post" class="dropzone">
<div class="dz-default dz-message"><span>Drop files here to upload</span></div>
<div class="fallback">
<input name="file" type="file" />
</div>
</form>
I got a Symfony2 controller who receive the post request.
// Get request
$request = $this->get('request');
// Get files
$files = $request->files;
// Upload
$do = $service->upload($files);
Uploading from the dropzone (by drag and drop or click) is working and the uploads are successfull but using the myDropzone.addFile() function return me an empty object in my controller :
var_dump($files);
return
object(Symfony\Component\HttpFoundation\FileBag)#11 (1) {
["parameters":protected]=>
array(0) {
}
}
I think i don't setup correctly my var file in the save function.
I tryied to create JS image (var img = new Image() ...) but without any success.
Thanks for your help !
Finally i found a working solution without creating canvas :
function dataURItoBlob(dataURI) {
'use strict'
var byteString,
mimestring
if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
byteString = atob(dataURI.split(',')[1])
} else {
byteString = decodeURI(dataURI.split(',')[1])
}
mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0]
var content = new Array();
for (var i = 0; i < byteString.length; i++) {
content[i] = byteString.charCodeAt(i)
}
return new Blob([new Uint8Array(content)], {type: mimestring});
}
And the save function :
function save(dataURI) {
var blob = dataURItoBlob(dataURI);
myDropzone.addFile(blob);
}
The file appears correctly in dropzone and is successfully uploaded.
I still have to work on the filename (my document is named "blob").
The dataURItoBlob function have been found here : Convert Data URI to File then append to FormData
[EDIT] : I finally wrote the function in dropzone to do this job. You can check it here : https://github.com/CasperArGh/dropzone
And you can use it like this :
var dataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAmAAAAKwCAYAAA...';
myDropzone.addBlob(dataURI, 'test.png');
I can't comment currently and wanted to send this to you.
I know you found your answer, but I had some trouble using your Git code and reshaped it a little for my needs, but I am about 100% positive this will work for EVERY possible need to add a file or a blob or anything and be able to apply a name to it.
Dropzone.prototype.addFileName = function(file, name) {
file.name = name;
file.upload = {
progress: 0,
total: file.size,
bytesSent: 0
};
this.files.push(file);
file.status = Dropzone.ADDED;
this.emit("addedfile", file);
this._enqueueThumbnail(file);
return this.accept(file, (function(_this) {
return function(error) {
if (error) {
file.accepted = false;
_this._errorProcessing([file], error);
} else {
file.accepted = true;
if (_this.options.autoQueue) {
_this.enqueueFile(file);
}
}
return _this._updateMaxFilesReachedClass();
};
})(this));
};
If this is added to dropzone.js (I did just below the line with Dropzone.prototype.addFile = function(file) { potentially line 1110.
Works like a charm and used just the same as any other. myDropzone.addFileName(file,name)!
Hopefully someone finds this useful and doesn't need to recreate it!
1) You say that: "Once the client have finished his job, he just have to click a save button which call the save function:"
This implies that you set autoProcessQueue: false and intercept the button click, to execute the saveFile() function.
$("#submitButton").click(function(e) {
// let the event not bubble up
e.preventDefault();
e.stopPropagation();
// process the uploads
myDropzone.processQueue();
});
2) check form action
Check that your form action="/upload" is routed correctly to your SF controller & action.
3) Example Code
You may find a full example over at the official Wiki
4) Ok, thanks to your comments, i understood the question better:
"How can i save my base64 image resource with dropzone?"
You need to embedd the image content as value
// base64 data
var dataURL = canvas.toDataURL();
// insert the data into the form
document.getElementById('image').value = canvas.toDataURL('image/png');
//or jQ: $('#img').val(canvas.toDataURL("image/png"));
// trigger submit of the form
document.forms["form1"].submit();
You might run into trouble doing this and might need to set the "origin-clean" flag to "true". see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#security-with-canvas-elements
how to save html5 canvas to server

How do you access other files stored on an website with JavaScript?

I am trying to write a webpage for a list of files to download. The files are stored with the webpage and I want the webpage to dynamically list all the files in the folder to download. That way when more are added I don't have to modify the webpage. I know how to use JavaScript to create links on the webpage but I need to use it to find the names of the files first.
I found a website that had code for navigating files like a file browser but it only uses a string to store the current location.
This is in the header:
<script type="text/javascript"><!--
var myloc = window.location.href;
var locarray = myloc.split("/");
delete locarray[(locarray.length-1)];
var fileref = locarray.join("/");
//--></script>
this is in the body:
<form>
<input type=button value="Show Files" onClick="window.location=fileref;">
</form>
However this doesn't really help since I am trying to create download links to files not have a file browser.
Edit:
When you host a traditional HTML page you upload the htmlfile and any images or content for the page to what ever server you use.
I want to use javascript to dynamically link to every file hosted with the webpage.
I am trying to combine this with hosting the files in a Dropbox public folder for a simple way to make the files available.
If you want a list of files on the server you will need to use a server-side script to gather their names:
JS--
//use AJAX to get the list of files from a server-side script
$.getJSON('path/to/server-side.php', { 'get_list' : 'true' }, function (serverResponse) {
//check the response to make sure it's a success
if (serverResponse.status == 'success') {
var len = serverResponse.output.length,
out = [];
//iterate through the serverResponse variable
for (var i = 0; i < len; i++) {
//add output to the `out` variable
out.push('<li>' + serverResponse.output[i] + '</li>');
}
//place new serverResponse output into DOM
$('#my-link-container').html('<ul>' + out.join('') + '</ul>');
} else {
alert('An Error Occured');
}
});
PHP--
<?php
//check to make sure the `get_list` GET variable exists
if (isset($_GET['get_list'])) {
//open the directory you want to use for your downloads
$handle = opendir('path/to/directory');
$output = array();
//iterate through the files in this directory
while ($file = readdir($handle)) {
//only add the file to the output if it is not in a black-list
if (!in_array($file, array('.', '..', 'error_log'))) {
$output[] = $file;
}
}
if (!empty($output)) {
//if there are files found then output them as JSON
echo json_encode(array('status' => 'success', 'output' => $output));
} else {
//if no files are found then output an error msg in JSON
echo json_encode(array('status' => 'error', 'output' => array()));
}
} else {
//if no `get_list` GET variable is found then output an error in JSON
echo json_encode(array('status' => 'error', 'output' => array()));
}
?>

Categories

Resources