Anyone can help me with my code? I wanna build an upload function using HTML5 API. if I upload less than 1mb the file is alright. However, if file more than 1mb the file will be corrupted.
the HTML file :
<!DOCTYPE html>
<html>
<head>
<title>Upload</title>
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
</head>
<body>
<form method="POST" action="upload.php" enctype='multipart/form-data'>
<input type="file" name="fileToUpload" id="file"><br />
<input type="submit" id="submit">
</form>
</body>
<script>
$(document).ready(function(){
$('#submit').on('click', function(e){
e.preventDefault();
sendRequest();
});
//window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
var bytes_per_chunk = 1048576; // 1mb chunk sizes.
var global_upload_counter = 0;
function sendRequest(){
var blob = document.getElementById('file').files[0];
var total_size = blob.size;
var start = 0;
var end = bytes_per_chunk;
// var counter = 1;
while(start < total_size)
{
// console.log('start : ' + start + ', end :' + end + ' and counter : ', counter);
var chunk = blob.slice(start, end);
uploadFile(chunk, blob.name);
start = end;
end = start + bytes_per_chunk;
//counter++;
}
}
function uploadFile(chunk, filename){
var fd = new FormData();
fd.append('fileToUpload', chunk);
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', uploadComplete, false);
xhr.addEventListener('error', uploadFailed, false);
xhr.addEventListener('abort', uploadCanceled, false);
xhr.open('POST', 'upload.php?filename=' + filename);
xhr.send(fd);
}
function uploadComplete(evt) {
// This event is raised when the server send back a response
if (evt.target.responseText != ""){
alert(evt.target.responseText);
}
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
}
function uploadCanceled(evt) {
xhr.abort();
xhr = null;
}
});
</script>
</html>
PHP code (upload.php):
<?php
$target_path = "upload/";
$tmp_name = $_FILES['fileToUpload']['tmp_name'];
$size = $_FILES['fileToUpload']['size'];
$name = $_FILES['fileToUpload']['name'];
$filename = $_GET['filename'];
//$target_file = $target_path.$name;
$complete = $target_path. $filename;
// append; open or create binary file for writing at end-of-file
$com = fopen($complete, "ab");
error_log($target_path);
// read as binary
$in = fopen($tmp_name, "rb");
if($in){
while ($buff = fread($in, $size)){
fwrite($com, $buff);
}
}
fclose($in);
First of all, why do you want to separate the file into chunks? You can upload the whole file in a go via AJAX. The error that you are encountering might be due to the chunk logic.
Try removing the chunk logic and it will work just fine. So your upload function would look something like this:
$(document).ready(function(){
$('#submit').on('click', function(e){
e.preventDefault();
sendRequest();
});
//window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
var bytes_per_chunk = 1048576; // 1mb chunk sizes.
var global_upload_counter = 0;
function sendRequest(){
var blob = document.getElementById('file').files[0];
var total_size = blob.size;
uploadFile(blob,filename);
}
function uploadFile(chunk, filename){
var fd = new FormData();
fd.append('fileToUpload', chunk);
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', uploadComplete, false);
xhr.addEventListener('error', uploadFailed, false);
xhr.addEventListener('abort', uploadCanceled, false);
xhr.open('POST', 'upload.php?filename=' + filename);
xhr.send(fd);
}
function uploadComplete(evt) {
// This event is raised when the server send back a response
if (evt.target.responseText != ""){
alert(evt.target.responseText);
}
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
}
function uploadCanceled(evt) {
xhr.abort();
xhr = null;
}
});
Instead of chunks, send the full file and it should work.
If you are worried about the upload progress, here are a few solutions:
jQuery Upload Progress and AJAX file upload ,
File upload progress bar with jQuery
Looking at the answer provided by user470714 on uploading a file in chunks using html5 I found the issues.
Which the ajax didn't actually uploading the chunks in order. So I updated my HTML code as follow and now it works fine :
<!DOCTYPE html>
<html>
<head>
<title>Upload</title>
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
</head>
<body>
<form method="POST" action="upload.php" enctype='multipart/form-data'>
<input type="file" name="fileToUpload" id="file"><br />
<input type="submit" id="submit">
</form>
</body>
<script>
$(document).ready(function(){
$('#submit').on('click', function(e){
e.preventDefault();
sendRequest();
});
//window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
var bytes_per_chunk = 1048576; // 1mb chunk sizes.
var global_upload_counter = 0;
function sendRequest(){
var blob = document.getElementById('file').files[0];
var total_size = blob.size;
window.upload_counter = 0;
window.upload_filearray = [];
var start = 0;
var end = bytes_per_chunk;
while(start < total_size)
{
var chunk = blob.slice(start, end);
window.upload_filearray[window.upload_counter] = chunk;
window.upload_counter++;
start = end;
end = start + bytes_per_chunk;
}
// initiate upload the first time
window.upload_counter = 0;
window.filename = blob.name;
uploadFile(window.upload_filearray[window.upload_counter]);
}
function uploadFile(chunk){
var fd = new FormData();
fd.append('fileToUpload', chunk);
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', uploadComplete, false);
xhr.addEventListener('error', uploadFailed, false);
xhr.addEventListener('abort', uploadCanceled, false);
xhr.open('POST', 'upload.php?filename=' + window.filename);
window.upload_counter++;
xhr.send(fd);
}
function uploadComplete(evt) {
// This event is raised when the server send back a response
if (evt.target.responseText != ""){
console.log(evt.target.responseText);
}
if(window.upload_filearray.length > window.upload_counter){
uploadFile(window.upload_filearray[window.upload_counter]);
}
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
}
function uploadCanceled(evt) {
xhr.abort();
xhr = null;
}
});
</script>
</html>
Related
I have a small test application to record the camera and sent the file to a directory on my server.
The main file is as follow:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.WebRTC-Experiment.com/RecordRTC.js"></script>
<style>
video {
max-width: 100%;
border: 5px solid yellow;
border-radius: 9px;
}
body {
background: black;
}
h1 {
color: yellow;
}
</style>
</head>
<body>
<h1 id="header">RecordRTC Upload to PHP</h1>
<video id="your-video-id" controls="" autoplay=""></video>
<script type="text/javascript">
// capture camera and/or microphone
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(function(camera) {
// preview camera during recording
document.getElementById('your-video-id').muted = true;
document.getElementById('your-video-id').srcObject = camera;
// recording configuration/hints/parameters
var recordingHints = {
type: 'video'
};
// initiating the recorder
var recorder = RecordRTC(camera, recordingHints);
// starting recording here
recorder.startRecording();
// auto stop recording after 5 seconds
var milliSeconds = 5 * 1000;
setTimeout(function() {
// stop recording
recorder.stopRecording(function() {
// get recorded blob
var blob = recorder.getBlob();
// generating a random file name
var fileName = getFileName('webm');
// we need to upload "File" --- not "Blob"
var fileObject = new File([blob], fileName, {
type: 'video/webm'
});
uploadToPHPServer(fileObject, function(response, fileDownloadURL) {
if(response !== 'ended') {
document.getElementById('header').innerHTML = response; // upload progress
return;
}
document.getElementById('header').innerHTML = '' + fileDownloadURL + '';
alert('Successfully uploaded recorded blob.');
// preview uploaded file
document.getElementById('your-video-id').src = fileDownloadURL;
// open uploaded file in a new tab
window.open(fileDownloadURL);
});
// release camera
document.getElementById('your-video-id').srcObject = null;
camera.getTracks().forEach(function(track) {
track.stop();
});
});
}, milliSeconds);
});
function uploadToPHPServer(blob, callback) {
// create FormData
var formData = new FormData();
formData.append('video-filename', blob.name);
console.log("blob.name:");
console.log(blob.name);
formData.append('video-blob', blob);
callback('Uploading recorded-file to server.');
makeXMLHttpRequest('https://xxx/yyy/', formData, function(progress) {
if (progress !== 'upload-ended') {
callback(progress);
return;
}
var initialURL = 'https://xxx/yyy/' + blob.name;
callback('ended', initialURL);
});
}
function makeXMLHttpRequest(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
if (request.responseText === 'success') {
callback('upload-ended');
return;
}
alert(request.responseText);
return;
}
};
request.upload.onloadstart = function() {
callback('PHP upload started...');
};
request.upload.onprogress = function(event) {
callback('PHP upload Progress ' + Math.round(event.loaded / event.total * 100) + "%");
};
request.upload.onload = function() {
callback('progress-about-to-end');
};
request.upload.onload = function() {
callback('PHP upload ended. Getting file URL.');
};
request.upload.onerror = function(error) {
callback('PHP upload failed.');
};
request.upload.onabort = function(error) {
callback('PHP upload aborted.');
};
request.open('POST', url);
request.send(data);
}
// this function is used to generate random file name
function getFileName(fileExtension) {
var d = new Date();
var year = d.getUTCFullYear();
var month = d.getUTCMonth();
var date = d.getUTCDate();
return 'RecordRTC-' + year + month + date + '-' + getRandomString() + '.' + fileExtension;
}
function getRandomString() {
if (window.crypto && window.crypto.getRandomValues && navigator.userAgent.indexOf('Safari') === -1) {
var a = window.crypto.getRandomValues(new Uint32Array(3)),
token = '';
for (var i = 0, l = a.length; i < l; i++) {
token += a[i].toString(36);
}
return token;
} else {
return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
}
}
</script>
</body>
</html>
in the location where the files are stored I have the following file
<?php
// path to ~/tmp directory
$tempName = $_FILES['video-blob']['tmp_name'];
// move file from ~/tmp to "uploads" directory
if (!move_uploaded_file($tempName, $filePath)) {
// failure report
echo getcwd();
echo " | ";
echo 'Problem saving file: '.$tempName .' to ' .$filePath .' Not uploaded because of error #'.$_FILES['video-blob']['error'];
if (!is_writable($filePath)) {
echo " | ";
echo "dir not writable or existing";
}
die();
}
// success report
echo 'success';
?>
When I run this on my local server it works fine. But when I upload it to my windows 2012 R2 server I get the error
POST https://xxx/yyy/ 405 (Method Not Allowed)
I tried to play with the handler mappings in ISS and disabled WebDAV but no luck.
Since it works on the localhost but not on the windows server I figure it must be something related with the IIS setting but can not find out what.
Any help is appreciated.
In the end I found the error myself.
The settings in the web.config file where not standing correctly for FastCgiModule / StaticFileModules.
I am using web workers for uploading larger file by creating chunks using slice but when I am sending the file in the form of formData object, it is throwing this error.when I do this in reactjs it is throwing following error
react-dom.development.js:518 Warning: React does not recognize the offClick prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase offclick instead. If you accidentally passed it from a parent component, remove it from the DOM element.
here is my code, where I am passing formData object to worker using postMessage, please help me to resolve this
<!DOCTYPE html>
<html>
<head>
<title>Using FileReaderSync Example</title>
<script id="worker1" type="javascript/worker">
var file = [], p = true;
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'url', true);//add url to upload
xhr.onload = function(e) {
};
xhr.send(blobOrFile);
}
function process() {
for (var j = 0; j <file.length; j++) {
var blob = file[j];
const BYTES_PER_CHUNK = 1024 * 1024;
// 1MB chunk sizes.
const SIZE = blob.size;
var start = 0;
var end = BYTES_PER_CHUNK;
while (start < SIZE) {
if ('mozSlice' in blob) {
var chunk = blob.mozSlice(start, end);
} else {
var chunk = blob.slice(start, end);
}
upload(chunk);
start = end;
end = start + BYTES_PER_CHUNK;
}
p = ( j = file.length - 1) ? true : false;
self.postMessage(blob.name + " Uploaded Succesfully");
}
}
self.addEventListener('message', function(e) {
for (var j = 0; j < e.data.files.length; j++)
file.push(e.data.files[j]);
if (p) {
process()
}
})
</script>
<script>
var blob = new Blob([document.querySelector('#worker1').textContent]);
var worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = function(e) {
alert(e.data);
};
worker.onerror =werror;
function werror(e) {
console.log('ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message);
}
function handleFileSelect(evt) {
console.log("coming");
evt.stopPropagation();
evt.preventDefault();
let files = new FormData();
files.append('file', event.target.files );
//var files = evt.target.files;
// FileList object.
worker.postMessage({
'files' : files
});
//Sending File list to worker
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes, last modified: ', f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a', '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
// Explicitly show this is a copy.
}
function getd(){
document.getElementById('files').addEventListener('change', handleFileSelect, false);
}
window.addEventListener("load", getd, false);
</script>
</head>
<body>
<input type="file" id="files" name="files[]"/>
<output id="list"></output>
</body>
</html>
You do not use the worker API properly. You should have a look to this https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
your worker file should looks like:
self.onmessage = function(e) {
// Do all the work here the postMessage the result
self.postMessage(result)
}
You "main" file is good :)
const worker = new Worker('yourWorkerFilePath')
worker.onmessage() = function(resultFormWorker) {
// treate the result here
}
worker.postMessage(file)
I have read some of the previous questions on this topic but I really need to be 100% sure!
Is it possible to read from a .txt file on my local system and present it in my HTML-BODY?
I have tried several functions, here is one:
function readFile (path) {
var fso = new ActiveXObject('Scripting.FileSystemObject'),
iStream=fso.OpenTextFile(path, 1, false);
while(!iStream.AtEndOfStream) {
document.body.innerHTML += iStream.ReadLine() + '<br/>';
}
iStream.Close();
}
readFile("testing.txt");
The content of the file is simply around 100 words I want to read from the text file and display in my HTML-BODY.
Is this possible without having my own server?
You can use a FileReader object to read text file here is example code:
<div id="page-wrapper">
<h1>Text File Reader</h1>
<div>
Select a text file:
<input type="file" id="fileInput">
</div>
<pre id="fileDisplayArea"><pre>
</div>
<script>
window.onload = function() {
var fileInput = document.getElementById('fileInput');
var fileDisplayArea = document.getElementById('fileDisplayArea');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(e) {
fileDisplayArea.innerText = reader.result;
}
reader.readAsText(file);
} else {
fileDisplayArea.innerText = "File not supported!"
}
});
}
</script>
Here is the codepen demo
If you have a fixed file to read every time your application load then you can use this code :
<script>
var fileDisplayArea = document.getElementById('fileDisplayArea');
function readTextFile(file)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
fileDisplayArea.innerText = allText
}
}
}
rawFile.send(null);
}
readTextFile("file:///C:/your/path/to/file.txt");
</script>
Please find below the code that generates automatically the content of the txt local file and display it html. Good luck!
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
var x;
if(navigator.appName.search('Microsoft')>-1) { x = new ActiveXObject('MSXML2.XMLHTTP'); }
else { x = new XMLHttpRequest(); }
function getdata() {
x.open('get', 'data1.txt', true);
x.onreadystatechange= showdata;
x.send(null);
}
function showdata() {
if(x.readyState==4) {
var el = document.getElementById('content');
el.innerHTML = x.responseText;
}
}
</script>
</head>
<body onload="getdata();showdata();">
<div id="content"></div>
</body>
</html>
What i'm trying to do here is to broadcast a file to other clients connected to the server via websocket/binaryjs using a binaryjs client/server system.
The problem comes with large files (or maybe is totally random?!?!). The client stops sending data to the server giving an error.
This is the first time i try something like this and i'm pretty new to socket programming so i might be missing something.... or everything.
Here is the client
<html>
<head>
<script src="http://cdn.binaryjs.com/0/binary.js" type="text/javascript" language="javascript"></script>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" language="javascript"></script>
<script>
$(document).ready(start);
function upload(e){
var file = e.target.files[0];
var chunkSize = 1024 * 1024; //1mb in this case but the problem seems to be uneffected by the chunk size
var fileSize = file.size;
var start = 0;
var end = chunkSize;
var s = client.createStream({name: file.name, size: file.size});
while(start < fileSize) {
w = s.write(file.slice(start, end));
console.log(w);
start = end;
end = start + chunkSize;
}
/*
//the client.send way
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
client.send(contents, {name: file.name, size: file.size});
};
reader.readAsArrayBuffer(file);
*/
}
var client = new BinaryClient('ws://0.0.0.0');
function start() {
var o = $('#output');
client.on('stream', function(stream, meta){
var parts = [];
var meta = meta;
var downloaded = 0;
var element = $('<div />');
o.append(element);
stream.on('data', function(data){
downloaded += data.byteLength;
element.html(meta.name+' '+(Math.round(downloaded/meta.size*100 *100)/100)+'% ');
parts.push(data);
});
stream.on('end', function(){
var a = document.createElement("a");
a.innerHTML='download';
a.href = (window.URL || window.webkitURL).createObjectURL(new Blob(parts));
a.download = meta.name;
a.target = '_blank';
element.append(a);
});
});
}
</script>
</head>
<body>
<input type="file" id="files" name="files" />
<div id="output"></div>
<script>
document.getElementById('files').addEventListener('change', upload, false);
</script>
</body>
</html>
And then comes the server code
var BinaryServer = require('binaryjs').BinaryServer;
var server = BinaryServer({port:80});
var clients = [];
server.on('connection', function(client){
clients.push(client);
console.log(clients.length);
client.on('stream', function(stream, meta){
var s = [];
var d = 0;
for (var i=0;i<clients.length;i++) {
if (clients[i].id == client.id) {
} else {
s.push(clients[i].createStream(meta));
}
}
var name = meta;
var parts = [];
stream.on('data', function(data){
d += data.length;
console.log('data in '+d);
for (var i=0;i<s.length;i++) {
s[i].write(data);
}
});
stream.on('end', function(){
console.log('end');
for (var i=0;i<s.length;i++) {
s[i].end();
}
});
});
client.on('close', function() {
for (var i=0;i<clients.length;i++) {
if(clients[i].id == client.id) {
clients.splice(i, 1);
}
}
client.close();
});
client.on('error', function(){
console.log('error');
});
});
While uploading from the client, i get this error message at random moments (client binary.js)
WebSocket connection to 'ws://0.0.0.0/' failed: Failed to send WebSocket frame. binary.js:1341
WebSocket connection to 'ws://0.0.0.0/' failed: Failed to load Blob: error code = 3 binary.js:1341
No problem with small files (for instance it NEVER fails broadcasting a 25mb wmv). Dunno if it's just a coincidence.
Any help would be appreciated.
Hi everyone and happy new year :)
I want to upload a file using XHR and web workers, sending chunks of the file and merging at the end. The problem is that the end file is empty, I think that the issue is in the content type of XHR request that will should send a correct "multipart/form-data" (when uploading a chunk), since that PHP print_r($_FILES) returns an empty Array() but in the web worker it's not possible to use FormData(). Help me to resolve this trouble, please :'(
index.html
<form onsubmit="return false" enctype="multipart/form-data">
<input id="file" type="file">
<div id="filedrop">or drop files here</div>
</form>
<script>
window.addEventListener("load", function() {
var fileselect = document.getElementById("file");
fileselect.addEventListener("change", FileSelectHandler, false);
var filedrag = document.getElementById("filedrop");
filedrag.addEventListener("dragover", FileDragHover, false);
filedrag.addEventListener("dragleave", FileDragHover, false);
filedrag.addEventListener("drop", FileSelectHandler, false);
}, false);
function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
}
function FileSelectHandler(e) {
FileDragHover(e);
var blob = e.target.files[0] || e.dataTransfer.files[0];
worker = new Worker("upload.webworker.js");
worker.postMessage(blob);
worker.onmessage = function(e) {
console.log(e);
};
}
</script>
uploadFile.php
<?
if ($_GET['a'] == "chunk") {
$target = "upload/" . $_GET['name'] . '-' . $_GET['index'];
move_uploaded_file($_FILES['file']['tmp_name'], $target);
sleep(1);
} else {
$target = "upload/" . $_GET['name'];
$dst = fopen($target, 'wb');
$slices = (int)$_GET['slices'];
for ($i = 0; $i < $slices; $i++) {
$slice = $target . '-' . $i;
$src = fopen($slice, 'rb');
stream_copy_to_stream($src, $dst);
fclose($src);
unlink($slice);
}
fclose($dst);
}
?>
upload.webworker.js
function uploadChunk(blob, index, start, end, slices, slices2) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
slices--;
if (slices == 0) {
var xhrMerge = new XMLHttpRequest();
xhrMerge.open("POST", "uploadFile.php?a=merge&name=" + blob.name + "&slices=" + slices2);
xhrMerge.onload = function() {
self.close();
};
xhrMerge.send();
}
};
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) self.postMessage(Math.round(100 / e.total * e.loaded)); //this doesn't work o.O
};
var chunk = blob.slice(start, end);
xhr.open("POST", "uploadFile.php?a=chunk&name=" + blob.name + "&index=" + index);
xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=--------------------");
xhr.send(chunk);
}
self.onmessage = function(e) {
const BYTES_PER_CHUNK = 1024 * 1024 * 32;
var blob = e.data,
start = 0,
index = 0,
slices = Math.ceil(blob.size / BYTES_PER_CHUNK),
slices2 = slices;
while (start < blob.size) {
end = start + BYTES_PER_CHUNK;
if (end > blob.size) end = blob.size;
uploadChunk(blob, index, start, end, slices, slices2);
start = end;
index++;
}
};
PS: if you want, tell me please how to optimize the upload in general =)
PPS: I'll should take advantages using synchronous ajax requests (only in the web worker) ?
PPPS: and if I to use php://input for reading chunk, it's better ?
I resolved reading file from php://input with this code:
$putdata = fopen("php://input", "r");
$fp = fopen($target, "w");
while ($data = fread($putdata, 16384)) {
fwrite($fp, $data);
}
fclose($fp);
fclose($putdata);
In this way, I don't need to write the HTTP headers of the multipart/form-data