I am trying to make a facebook like image uploader with the most basic methods. I select the multiple images on the input and then it creates the per file progress bars with names. It shows it's loading but it doesn't send to the upload.php file. I have the HTML code section:
<div class="container">
<h1>Uploader</h1>
<hr>
<form action="#" id="image_form">
<input type="file" id='image' name="image" multiple>
</form>
<div class="container">
<div class="filelist">
</div>
<ul id="uploads">
</ul>
</div>
Then I have my javascript. The progress bars get created with the file names and the progress is tracked. I have tried it with largish files and it does take a long while to upload. Progress bar shows this accurately.
$('#image').change(function (event) {
var files = this.files;
// iterate over each file to upload, send a request, and attach progress event
for (var i = 0, file; file = files[i]; i++) {
var li = $("<li>" + file.name + "<div class='progress progress-striped active'><div class='progress-bar' style='width:0%'>" + file.size + "</div></div></li>");
// add the LI to the list of uploading files
$("#uploads").append(li);
// fade in the LI instead of just showing it
li.hide().fadeIn();
var xhr = new XMLHttpRequest();
xhr.upload.li = li;
xhr.upload.addEventListener('progress', function(e) {
var percent = parseInt(e.loaded / e.total * 100);
this.li.find(".progress-bar").width(percent+'%');
}, false);
// setup and send the file
xhr.open('POST', 'upload.php', true);
xhr.setRequestHeader('X-FILE-NAME', file.name);
xhr.send(file);
}
});
I have been struggling with this piece of code for the last week and have been through almost every topic on this site without success. Please could someone help me figure out why I can't post the file details to the php script.
I'm using this code to post files to PHP:
function postFile(action, file, postFileName) {
var fPostName = typeof postFileName === 'undefined' ? 'file' : postFileName;
/* Create a FormData instance */
var formData = new FormData();
/* Add the file */
formData.append(fPostName, file);
var requestUrl = rootUrl + action;
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('POST', requestUrl);
/* handlers */
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
console.log(formData);
/* send request */
xhr.send(formData);
});
}
// Sample usage
* <<< FILE upload >>>>>>
* var file = document.getElementById('f').files[0];
* console.log(file);
* postFile('your_processing_script.php', file).then(function (response) {
* console.log(response);
* },function (er) {
* console.log(er);
* });
and then in PHP you should have:
$_FILES["file"] or $_FILES[postFileName]
Hope this helps you.
Cheers
Related
Having an issue with uploading images on Tiny. I want to upload the images to folder /images/owner/ I don't want a blob, but rather to upload full files.
I can upload to file_upload.php no problem from test.html. Containing a text input and a file input only. file_upload.php looks like this ...
<?php
/***************************************************
* Only these origins are allowed to upload images *
***************************************************/
$accepted_origins = array("http://localhost", "http://192.168.1.1", "https://example.com/");
/*********************************************
* Change this line to set the upload folder *
*********************************************/
$owner_id=$_POST["owner"];
//$owner_id='15601a2cc3d5b2';
$imageFolder = "images/". $owner_id . "/";
// Don't attempt to process the upload on an OPTIONS request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Methods: POST, OPTIONS");
return;
}
reset($_FILES);
$temp = current($_FILES);
if (is_uploaded_file($temp['tmp_name'])){
// Sanitize input
if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
header("HTTP/1.1 400 Invalid file name.");
return;
}
// Verify extension
if (!in_array(strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
header("HTTP/1.1 400 Invalid extension.");
return;
}
// Accept upload if there was no origin, or if it is an accepted origin
$filetowrite = $imageFolder . $temp['name'];
move_uploaded_file($temp['tmp_name'], $filetowrite);
// Determine the base URL
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? "https://" : "http://";
$baseurl = $protocol . $_SERVER["HTTP_HOST"] . rtrim(dirname($_SERVER['REQUEST_URI']), "/") . "/";
// Respond to the successful upload with JSON.
// Use a location key to specify the path to the saved image resource.
// { location : '/your/uploaded/image/file'}
echo json_encode(array('location' => $baseurl . $filetowrite));
} else {
// Notify editor that the upload failed
header("HTTP/1.1 500 Server Error");
}
?>
This Tiny JS code is on my editor.php page. I don't want a blob that can't be linked to. I want to send an email newsletter and only proper files/images on the server will render...
<script>
tinymce.init({
selector: '#mytextarea',
images_upload_handler: images_upload_handler,
plugins: 'image code',
toolbar: 'undo redo | link image',
/* enable title field in the Image dialog*/
image_title: true,
/* enable automatic uploads of images represented by blob or data URIs*/
automatic_uploads: true,
/*
URL of our upload handler (for more details check: https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_url)
images_upload_url: './js/tinymce/postAcceptor.php',
here we add custom filepicker only to Image dialog
*/
file_picker_types: 'image',
/* and here's our custom image picker*/
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
/*
Note: In modern browsers input[type=\"file\"] is functional without
even adding it to the DOM, but that might not be the case in some older
or quirky browsers like IE, so you might want to add it to the DOM
just in case, and visually hide it. And do not forget do remove it
once you do not need it anymore.
*/
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
/*
Note: Now we need to register the blob in TinyMCEs image blob
registry. In the next release this part hopefully won't be
necessary, as we are looking to handle it internally.
*/
var id = 'blobid' + (new Date()).getTime();
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var base64 = reader.result.split(',')[1];
var blobInfo = blobCache.create(id, file, base64);
blobCache.add(blobInfo);
/* call the callback and populate the Title field with the file name */
cb(blobInfo.blobUri(), { title: file.name });
};
reader.readAsDataURL(file);
};
input.click();
},
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }'
});
function images_upload_handler (blobInfo, success, failure, progress) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST','https://example.com/myfolder/file-upload.php');
xhr.upload.onprogress = function (e) {
progress(e.loaded / e.total * 100);
};
xhr.onload = function() {
var json;
if (xhr.status === 403) {
failure('HTTP Error: ' + xhr.status, { remove: true });
return;
}
if (xhr.status < 200 || xhr.status >= 300) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.location);
};
xhr.onerror = function () {
failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
};
formData = new FormData();
formData.append('owner','" . $owner_id . "');
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
};
When i do this from chrome web dev ...
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST','https://example.com/myfolder/file-upload.php');
formData = new FormData();
formData.append('owner','ddddddddd');
formData.append('file', '/home/me/Desktop/image/mail.png');
xhr.send(formData);
I get array(0) {}
I can't send both values, owner and file. I've stacked them in the correct order.
Also have to click upload on the Tiny editor image popup, when i use General it gives me a blob.
No luck. Sorry if this post is kinda verbose. Thought you'd need all the code to help...
I'm using TinyMCE 5 with PHP 7.
Currently:
1. images_upload_handler (working)
Following the TinyMCE guide on Drag-in uploading images, and my own PHP upload AJAX handler, I got an image to upload successfully to my uploads directory:
This correctly uploads the file and keeps the correct name, using AJAX.
It uses a function for images_upload_handler, calling my AJAX handler.
2. file_picker_callback (incomplete)
Following the TinyMCE demo on uploading files, I got these two toolbar buttons (image, media) to show an upload button in their dialogs:
This works for image, not media.
It uses a function for file_picker_callback, uploading its own way.
3. The problem
I can't get the file_picker_callback from 2. to upload from media and I want it to use my own AJAX upload handler anyway, which I can't.
Using the image tool to upload, it will save the file after clicking "Save" in the dialog. But, when used in the media tool, it will not upload or insert anything at all.
It seems that this JavaScript demo provided by TinyMCE has a heavy interaction with the TinyMCE API itself. It has a system of caching and blobs to find the file that TinyMCE uploaded on its own. So pure AJAX-JS knowledge isn't sufficient to tell me how to tell TinyMCE to use my own AJAX upload PHP file. I'd rather just override TinyMCE's upload handler in file_picker_callback so I can use my own PHP upload script to be compatible with the rest of my app.
Goal:
I need a function for file_picker_callback (the file upload button) to use my own AJAX upload handler and preserve the name just as images_upload_handler succeeds in doing.
I am not worried about filename and mimetype validation; I plan to have PHP sanitize and filter later on.
This Question addresses another file uploader and the problem of TinyMCE 4 solutions not always working with TinyMCE 5.
This Question is about image description, and only for images; I want to upload any filetype.
I do not want any dependencies, not even jQuery. Vanilla JS only.
Current Code:
| upload.php :
$temp_file = $_FILES['file']['tmp_name'];
$file_path_dest = 'uploads/'.$_FILES['file']['name'];
move_uploaded_file($temp_file, $file_path_dest);
$json_file_is_here = json_encode(array('filepath' => $file_path_dest));
echo $json_file_is_here;
| tinyinit.js :
tinymce.init({
selector: 'textarea',
plugins: [ 'image media imagetools', ],
automatic_uploads: true,
images_reuse_filename: true,
images_upload_url: 'upload.php',
// From #1. Successful AJAX Upload
images_upload_handler: function(fileHere, success, fail) {
var ajax = new XMLHttpRequest();
ajax.withCredentials = false;
ajax.open('post', 'upload.php');
ajax.upload.onprogress = function (e) {
progress(e.loaded / e.total * 100);
};
ajax.onload = function() {
if (ajax.status == 200) {
if ( (!JSON.parse(ajax.responseText))
|| (typeof JSON.parse(ajax.responseText).filepath != 'string') ) {
fail('Invalid: <code>'+ajax.responseText+'</code>');
return;
}
success(JSON.parse(ajax.responseText).filepath);
} else {
fail('Upload error: <code>'+ajax.status+'</code>');
return;
}
};
var fileInfo = new FormData();
fileInfo.append('file', fileHere.blob(), fileHere.filename());
ajax.send(fileInfo);
},
file_browser_callback_types: 'file image media',
file_picker_types: 'file image media',
// From #2. Neither uploads from "media" nor uses my upload handler
file_picker_callback: function(cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var base64 = reader.result.split(',')[1];
var blobInfo = blobCache.create(file.name, file, base64);
blobCache.add(blobInfo);
cb(blobInfo.blobUri(), { title: file.name });
};
reader.readAsDataURL(file);
};
input.click();
}
});
Editing #Aulia's Answer :
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
// FormData
var fd = new FormData();
var files = file;
fd.append('filetype',meta.filetype);
fd.append("file",files);
var filename = "";
// AJAX
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '/your-endpoint');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
alert('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
alert('Invalid JSON: ' + xhr.responseText);
return;
}
filename = json.location;
reader.onload = function(e) {
cb(filename);
};
reader.readAsDataURL(file);
};
xhr.send(fd);
return
};
input.click();
}
In the configuration you've provided, #2 doesn't have any logic to upload the data to your server. The code from Tiny's documentation you've copied is just for demo purposes and won't allow you to upload files to Tiny's servers.
You will need to setup the file_picker_callback callback to send data similar to images_upload_handler. On your server, you will need to send the URI and title in the response so the following line will be fulfilled:
cb(blobInfo.blobUri(), { title: file.name });
Hope it will helps mate, make your file_picker_callback looks like below codes
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
// FormData
var fd = new FormData();
var files = file;
fd.append('filetype',meta.filetype);
fd.append("file",files);
var filename = "";
// AJAX
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '/your-endpoint');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.location);
filename = json.location;
};
xhr.send(fd);
reader.onload = function(e) {
cb(filename);
};
reader.readAsDataURL(file);
return
};
input.click();
},
I am trying to make a UI for esp8226 html js, ajax everything works fine but when I try to upload the firmware(uxx.bin) file it doesn't work.
Reference : https://github.com/jeelabs/esp-link/blob/master/html/flash.js
Note : I am connected to same network using wifi and the html page loads quite good.
I am trying to upload two files 1 --> uxx.bin
once it uploads redirect to next page and upload 2 --> uyy.bin
Here is the code
Html
<form id="file-form" action="uxx.bin" method="POST">
<input type="file" id="file-select" name="user[]" multiple/>
<button type="submit" id="upload-button">Upload</button>
</form>
var form = document.getElementById('file-form');
var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('upload-button');
form.onsubmit = function(event) {
event.preventDefault();
// Update button text.
uploadButton.innerHTML = 'Uploading...';
var files = fileSelect.files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
// Check the file type.
if (!file.type.match('image.*')) {
continue;
}
// Add the file to the request.
formData.append('user[]', file, file.name);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', 'uxx.bin', true);
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
uploadButton.innerHTML = 'Upload';
} else {
alert('An error occurred!');
}
};
xhr.send(formData);
if anyone can guide with the correct approach :-)
I want to create an uploader with js. Can anyone help me how to upload a file using javascript?
You can use html5 file type like this:
<input type="file" id="myFile">
You file will be in value:
var myUploadedFile = document.getElementById("myFile").files[0];
For more information see https://www.w3schools.com/jsref/dom_obj_fileupload.asp
and see example here: https://www.script-tutorials.com/pure-html5-file-upload/
You can upload files with XMLHttpRequest and FormData. The example below shows how to upload a newly selected file(s).
<input type="file" name="my_files[]" multiple/>
<script>
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
const fd = new FormData();
// add all selected files
e.target.files.forEach((file) => {
fd.append(e.target.name, file, file.name);
});
// create the request
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
// we done!
}
};
// path to server would be where you'd normally post the form to
xhr.open('POST', '/path/to/server', true);
xhr.send(fd);
});
</script>
HTML Part:
<form enctype = "multipart/form-data" onsubmit="return false;" >
<input id="file" type="file" name="static_file" />
<button id="upload-button" onclick="uploadFile(this.form)"> Upload </button>
</form>
JavaScript Part:
function uploadFile(form){
const formData = new FormData(form);
var oOutput = document.getElementById("static_file_response")
var oReq = new XMLHttpRequest();
oReq.open("POST", "upload_static_file", true);
oReq.onload = function(oEvent) {
if (oReq.status == 200) {
oOutput.innerHTML = "Uploaded!";
console.log(oReq.response)
} else {
oOutput.innerHTML = "Error occurred when trying to upload your file.<br \/>";
}
};
oOutput.innerHTML = "Sending file!";
console.log("Sending file!")
oReq.send(formData);
}
In the above HTML, I'm using the form to capture the files and calling the JS function when the button is clicked. In the JS function, I'm using the XMLHttpRequest to send the file.
A detailed step-by-step document can be found here.
I'm not very practiced in using XMLHttpRequests, but I am working on a drag and drop file converter that takes a zip file and returns one in response. Most of it is working, but I'm not sure how to pick the zip file out of the response. Here's where I'm at:
dropZone[0].ondrop = function(event) {
// Stop the browser from opening the file in the window
event.preventDefault();
dropZone.removeClass('hover');
// Get the file and the file reader
var file = event.dataTransfer.files[0];
// Send the file
var xhr = new XMLHttpRequest();
// xhr.upload.addEventListener('progress', uploadProgress, false);
xhr.onreadystatechange = function(response) {
if (event.target.readyState == 4) {
alert("winner");
if (event.target.status == 200) {
$('#dropZone').text('Upload Complete!');
}
else {
dropZone.text('Upload Failed!');
dropZone.addClass('error');
}
}
};
xhr.open('POST', 'Home/handleFileUpload', true);
xhr.setRequestHeader('X-FILE-NAME', file.name);
xhr.send(file);
};
fiddler is showing a 200 with some binary results. How do I make the browswer save/download it as a zip?