lang/js/ AjaxUpload
This is a simple example using Javascript and PHP
Example 1
AJAX Core
The core that makes it work is
xhttp.open("POST", ".upload", true);
xhttp.onload = function (event) {
const responseText = this.responseText
console.log({responseText})
const response = JSON.parse(responseText)
console.log({response})
const status = xhttp.status
if (status == 200) {
const { result, error, files } = response
if (result === "error") {
display_error(error)
} else {
on_successful_upload(files, result)
}
} else {
// this will happen if you don't have write permission at time of upload (a 403)
display_error(`status ${status}: ${responseText}`)
}
}
xhttp.send(form_data);
and
foreach ($_FILES['file']['name'] as $key=>$val) {
$filename = $_FILES['file']['name'][$key];
$filename = preg_replace('/[^a-zA-Z0-9_\-@\. ]+/',"_",$filename);
$tmp_name = $_FILES['file']['tmp_name'][$key];
$target = trim($subdir,"/")."/".$filename;
if( ! $wiki->valid_file_path($target) ) {
array_push($files_results,make_error($filename,"Filename '$filename' is not acceptable"));
$failures++;
} else {
// filename ok
try {
$storage->store_uploaded($tmp_name,$target);
array_push($files_results,array("filename"=>$filename,"result"=>"success","error"=>null));
$successes++;
} catch( Exception $e ) {
array_push($files_results,make_error($filename,"Failed to move '$filename' -- ".$e->getMessage()));
$failures++;
}
}
}
everything else below is a wrapper
Javascript
//
// Code adapted from https://artisansweb.net/drag-drop-file-upload-using-javascript-php/
//
(function() {
window.addEventListener("load",_ => {
let fileobj
function upload_file(e) {
console.log({msg:"upload file"})
e.preventDefault()
ajax_file_upload(e.dataTransfer.files)
}
function filename_is_image(filename) {
return filename.match(/\.(jpg|jpeg|jfif|png|webp|gif|svg)$/)
}
function on_successful_upload(files, result) {
console.log({msg:"upload",files,result})
const successful_files = files.filter(x => x.result === "success" )
let msg
if( result === "partial" ) {
msg = `Partial success: ${successful_files.length}/${files.length} uploaded`
} else {
msg = `Success: ${successful_files.length}/${files.length} uploaded`
}
const msgarr = []
for(let i=0; i<files.length; i++) {
const f = files[i]
const { filename, result, error } = f
if( result === "error" ) {
msgarr.push(`<span class='upload_error'>${filename} — ${error}</span>`)
} else {
const img = filename_is_image(filename) ? ` <img src='${filename}'/>` : ""
msgarr.push(`<span class='upload_success'>${filename}${img}</span>`)
}
}
msg += "<br/>\n" + msgarr.join("<br/>\n")
// do something to tell the user the result
display_notification(msg,true) // supply this function yourself
}
// ACTUAL UPLOADER
function ajax_file_upload(files_obj) {
console.log(files_obj)
if (files_obj != undefined) {
var form_data = new FormData();
for (let i = 0; i < files_obj.length; i++) {
console.log(files_obj)
form_data.append('file[]', files_obj[i])
}
form_data.append('location',window.location.href)
console.log(`uploading`, files_obj);
display_notification(`Uploading ${Array.from(files_obj).map(x => x.name).join(", ")}`)
var xhttp = new XMLHttpRequest();
xhttp.open("POST", ".upload", true);
xhttp.onload = function (event) {
const responseText = this.responseText
console.log({responseText})
const response = JSON.parse(responseText)
console.log({response})
const status = xhttp.status
if (status == 200) {
const { result, error, files } = response
if (result === "error") {
display_error(error)
} else {
on_successful_upload(files, result)
}
} else {
// this will happen if you don't have write permission at time of upload (a 403)
display_error(`status ${status}: ${responseText}`)
}
}
xhttp.send(form_data);
}
}
})
})()
PHP
php
#
# Code adapted from https://artisansweb.net/drag-drop-file-upload-using-javascript-php/
#
function store_uploaded_file($tmp_name,$filename) {
return move_uploaded_file($tmp_name,$filename);
}
function return_error(string $msg, int $response_code = 400) : void {
http_response_code($response_code);
file_put_contents("error.txt",$msg);
echo json_encode(["error" => $msg]);
die;
}
function return_json($obj) : void {
echo json_encode($obj);
die;
}
function make_error($filename,$error) {
return array("filename" => $filename, "result"=> "error", "error"=>$error);
}
umask(0);
$status = "success";
$error = null;
$files_results = array();
$successes = 0;
$failures = 0;
if( ! isset($_POST) || ! array_key_exists('location',$_POST) ) {
return_error("Invalid upload data -- no location");
}
$location = parse_url($_POST['location']);
$path = urldecode($location['path']);
$subdir = dirname($path);
foreach ($_FILES['file']['name'] as $key=>$val) {
$filename = $_FILES['file']['name'][$key];
$filename = preg_replace('/[^a-zA-Z0-9_\-@\. ]+/',"_",$filename);
$tmp_name = $_FILES['file']['tmp_name'][$key];
$target = trim($subdir,"/")."/".$filename;
if( ! $wiki->valid_file_path($target) ) {
array_push($files_results,make_error($filename,"Filename '$filename' is not acceptable"));
$failures++;
} else {
// filename ok
try {
$storage->store_uploaded($tmp_name,$target);
array_push($files_results,array("filename"=>$filename,"result"=>"success","error"=>null));
$successes++;
} catch( Exception $e ) {
array_push($files_results,make_error($filename,"Failed to move '$filename' -- ".$e->getMessage()));
$failures++;
}
}
}
$return_obj = array(
"error"=> ($successes == 0 ? "No files uploaded" : null),
"result"=> ($successes > 0 && $failures == 0 ? "success" : ($successes > 0 && $failures > 0 ? "partial" : "error" )),
"files"=> $files_results
);
$json = json_encode($return_obj);
echo $json;
exit();