I'm trying to add a Progress Bar to track the file Upload status of my Form. To upload files I use this Form code:
<form id="contact-form" action="awsUpload.php" method="post" name="frmImage" enctype="multipart/form-data">
<input class="file-input" type="file" style="width:100%;"autocomplete="off" name="ftp" accept="image/*, .zip, .rar, .bzip" onchange="this.form.submit();changeStyle()" class="file-up" id="fileFTP">
</form>
And this PHP code to manage the File Upload request.
<?php
require './aws/aws-autoloader.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
// AWS Info
$bucketName = '***';
$IAM_KEY = '***';
$IAM_SECRET = '***';
// Connect to AWS
try {
// You may need to change the region. It will say in the URL when the bucket is open
// and on creation. us-east-2 is Ohio, us-east-1 is North Virgina
$s3 = S3Client::factory(array(
'credentials' => array(
'key' => $IAM_KEY,
'secret' => $IAM_SECRET
),
'version' => 'latest',
'region' => 'eu-west-1'
));
}
catch (Exception $e) {
die("Error: " . $e->getMessage());
}
// For this, I would generate a unqiue random string for the key name. But you can do whatever.
//$target_file = 'f/' . basename($_FILES["ftp"]['tmp_name']); //ftp is file name at index.php
if (isset($_FILES["ftp"]) && $_FILES["ftp"]["error"] == 0) {
$mimeType = mime_content_type($_FILES["ftp"]["tmp_name"]);
$fileSize = $_FILES["ftp"]["size"];
if (strpos($mimeType, "image") === 0) {
if ($fileSize <= 1000 * 1024 * 1024) { //max image size
$target_dir = "i/";
// $strng = preg_replace("/[\s-]|\#/", "_", basename($_FILES["ftp"]["name"])); //Prima era solo "/[\s-]/"
$target_file = $target_dir . time() . rand(100, 999);
//$pathInS3 = 'https://s3.ap-south-1.amazonaws.com/' . $bucketName . '/' . $target_file;
// Add it to S3
try {
if (!file_exists('/tmp/tmpfile')) {
echo 3;
mkdir('/tmp/tmpfile');
}
$tempFilePath = '/tmp/tmpfile/' . basename($_FILES["ftp"]['name']);
$tempFile = fopen($tempFilePath, "w") or die("Error: Unable to open file.");
$fileContents = file_get_contents($_FILES["ftp"]['tmp_name']);
$tempFile = file_put_contents($tempFilePath, $fileContents);
$s3->putObject(array(
'Bucket' => $bucketName,
'Key' => $target_file,
'SourceFile' => $tempFilePath,
'StorageClass' => 'REDUCED_REDUNDANCY',
'ACL' => 'public-read'
));
$valPOutput = htmlspecialchars($target_file);
header('HTTP/1.1 303 See Other');
header('Location: http://example.com/result.php' . "?p=" . $valPOutput);
}
catch (S3Exception $e) {
die('Error:' . $e->getMessage());
}
catch (Exception $e) {
die('Error:' . $e->getMessage());
}
} else {
echo "image too big";
}
} elseif ($mimeType == "application/zip" || $mimeType == "application/x-rar-compressed" || $mimeType == "application/x-7z-compressed" || $mimeType == "application/x-bzip2") {
if ($fileSize <= 5000 * 1024 * 1024) { //max arch size
$target_dir = "f/";
//$strng = preg_replace("/[\s-]|\#/", "_", basename($_FILES["ftp"]["name"])); //Prima era solo "/[\s-]/"
$target_file = $target_dir . time() . rand(100, 999);
// $pathInS3 = 'https://s3.ap-south-1.amazonaws.com/' . $bucketName . '/' . $target_file;
// Add it to S3
try {
if (!file_exists('/tmp/tmpfile')) {
echo 3;
mkdir('/tmp/tmpfile');
}
$tempFilePath = '/tmp/tmpfile/' . basename($_FILES["ftp"]['name']);
$tempFile = fopen($tempFilePath, "w") or die("Error: Unable to open file.");
$fileContents = file_get_contents($_FILES["ftp"]['tmp_name']);
$tempFile = file_put_contents($tempFilePath, $fileContents);
$s3->putObject(array(
'Bucket' => $bucketName,
'Key' => $target_file,
'SourceFile' => $tempFilePath,
'StorageClass' => 'REDUCED_REDUNDANCY',
'ACL' => 'public-read'
));
$valPOutput = htmlspecialchars($target_file);
header('HTTP/1.1 303 See Other');
header('Location: http://example.com/result.php' . "?p=" . $valPOutput);
}
catch (S3Exception $e) {
die('Error:' . $e->getMessage());
}
catch (Exception $e) {
die('Error:' . $e->getMessage());
}
}else {
echo "arch too big";
}
}
}
?>
I've tried to do so adding event listeners to prevent submitting request, but when I upload a file, the website URL changes from https://example.com to https://example.com/awsUpload.php and the Progress Bar does not move and the Upload keeps going.
I'd like to receive some suggestions on how I can move or think to achieve that (the code I posted right now does not include any Progress bar test since I deleted the progress bar code cause it did not work).
EDIT DOWN HERE Modified the form and added this new Script. Right now the Load bar does work and the file gets uploaded, unfortunately I do not know why after the form gets submitted I do not get redirected to https://example.com/?p=****
<form id="contact-form" action="awsUpload.php" method="post" name="frmImage" enctype="multipart/form-data">
<input class="file-input" type="file" style="width:100%;"autocomplete="off" name="ftp" accept="image/*, .zip, .rar, .bzip" onchange="uploadFile(this.form)" class="file-up" id="fileFTP">
<progress id="upload-progress" value="0" max="100"></progress>
</form>
<script>
function uploadFile(form) {
var fileInput = form.querySelector('input[type="file"]');
var file = fileInput.files[0];
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open('POST', this.form, true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
var progressBar = form.querySelector('progress');
progressBar.value = percentComplete;
}
};
xhr.onload = function() {
if (xhr.status == 200) {
// File uploaded successfully
alert('success')
} else {
// An error occurred during the upload
}
};
xhr.send(formData);
}
</script>
Extra: I tried to ad in the action of if (xhr.status == 200) to redirect to a certain webpage with window.location but I'm missing the $valPOutput from the awsUpload.php and do not know how to get it.