Hi Im trying to upload a 2 file or more, my problem is my progress bar will say 100% because of the small file being uploaded first, then its going back to the percent of the large file.. My question is how can I have a same progress if i have many files being uploaded?
for (var i = 0, f; f = files.files[i]; i++) {
$.ajax({
xhr: function(){
//upload Progress
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//update progressbar
$('.bar').width(percent + '%');
}, true);
}
return xhr;
},
url: 'https://content.dropboxapi.com/2/files/upload',
type: 'post',
data: f,
processData: false,
contentType: 'application/octet-stream',
headers: {
"Authorization": "Bearer ACCESS TOKEN",
"Dropbox-API-Arg": '{"path": "/'+f.name+'", "mode": "add","autorename": true,"mute": false}'
},
success: function (data) {
console.log(data);
app.alert.show('success-message', {
level: 'success',
messages: 'your file has been upload to Dropbox',
autoClose: true
});
},
error: function (data) {
console.log(data);
}
})
}
I think you should store progress of each file in different variable (or maybe array of variables) and write function, that will update progressbar width when this vars are changed.
Related
I create a simple website for Uploading files on Google Drive using Google Drive Api.
This is My Code :
$.ajax({
type: "POST",
beforeSend: function(request) {
request.setRequestHeader("Authorization", "Bearer" + " " + localStorage.getItem("accessToken"));
},
url: "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart&fields=webViewLink",
data:{
uploadType:"media"
},
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener('progress', that.progressHandling, false);
}
return myXhr;
},
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
},
async: true,
data: formData,
cache: false,
contentType: false,
processData: false,
timeout: 60000
});
};
Upload.prototype.progressHandling = function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
var progress_bar_id = "#progress-wrp";
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// update progressbars classes so it fits your code
$(progress_bar_id + " .progress-bar").css("width", +percent + "%");
$(progress_bar_id + " .status").text(percent + "%");
};
$("#upload").on("click", function (e) {
var file = $("#files")[0].files[0];
var upload = new Upload(file);
// maby check size or type here with upload.getSize() and upload.getType()
// execute upload
upload.doUpload();
});
});
Everything is Oky, But I just want to get the public URL of The files 😠I just want to show the public url after file uploaded. Help Me Please
after upload the file and getting the fileId:
async function generatePublicUrl(fileId) {
try {
await drive.permissions.create({
fileId: fileId,
requestBody: {
role: "reader",
type: "anyone",
},
});
const result = await drive.files.get({
fileId: fileId,
fields: "webViewLink, webContentLink",
});
return result;
} catch (err) {
console.log(err);
}
}
and after doing that you just put your fileId in the format:
https://drive.google.com/file/d/"yourfileId"/preview
The Google Drive api does not have a method for creating the sharable link.
You will need to manually go to the Google drive website and create your sharable link there and store it in your system.
i have a Problem with my Ajax-Fileupload Script.
When I upload my Files, the Files are corrupt. When I open the File with Notepad++, i see that there are for example the following Lines:
-----------------------------22998260013704
Content-Disposition: form-data; name="0"; filename="myimage.png"
Content-Type: image/png
filecontent
-----------------------------22998260013704--
When I delete the 3 Lines bevor filecontent und the Line after filecontent, the File is ok.
I have no clue, why these 4 Lines are written to the Files.
I hope that somebody can help me.
Here is my Javascript-Code:
var myFiles = [];
function ajaxFileUpload() {
var dataid = document.getElementById("dataid").getAttribute("data-id"),
data = new FormData(),
maxSize = 100.0,
file = null,
myUrl = "xxx/save";
$.each(myFiles, function(key, value) {
console.log(key+" "+value);
file = value;
data.append(key, value);
});
var filesize = file.size;
if ((filesize/(1024*1024)) <= maxSize) {
$.ajax({
type: "PUT", //<-- http://stackoverflow.com/questions/10475313/ajax-file-upload-with-xmlhttprequest
url: myUrl,
processData: false,
contentType: false,
data: data,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-myid", dataid);
},
success: function (json) {
//....
},
});
} else {
//...
}
}
And here my relevant PHP-Code:
private function copyPutFilesToTmp($directory = "") {
$temp = "xxx";
if (!is_dir($temp)) {
mkdir ($temp, 0777, true);
}
$tmpPath = $temp."/";
$filename = $_SERVER['HTTP_X_FILE_NAME'];
$in = fopen('php://input', 'r');
$ziel = $tmpPath.$filename;
if (!file_exists($ziel)) {
$fileuploadok = true;
$out = fopen($ziel, 'w');
$data = fread($in, 1024);
while($data) {
if ($data != false) {
fwrite($out, $data);
} else {
$fileuploadok = false;
}
$data = fread($in, 1024);
}
fclose($in);
fclose($out);
if ($fileuploadok === FALSE) {
//...
} else {
//...
}
} else {
//...
}
return $answer;
}
I found the problem.
if I sent the file directly as data and not within a FormData it works!
So the right Code is:
var myFiles = [];
function ajaxFileUpload() {
var dataid = document.getElementById("dataid").getAttribute("data-id"),
maxSize = 100.0,
file = null,
myUrl = "xxx/save";
$.each(myFiles, function(key, value) {
file = value;
});
var filesize = file.size;
if ((filesize/(1024*1024)) <= maxSize) {
$.ajax({
type: "PUT", //<-- https://stackoverflow.com/questions/10475313/ajax-file-upload-with-xmlhttprequest
url: myUrl,
processData: false,
contentType: false,
data: file,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-myid", dataid);
},
success: function (json) {
//....
},
});
} else {
//...
}
}
found here: AJAX File Upload with XMLHttpRequest
I am generating a signature for doing client side posting to s3 in node on the back end and submitting it via jquery-file-upload on the client. My signature generation looks like the following:
app.post('/api/v1/s3', function(req, res){
var data = utils.getReqJson(req.body);
var mime_type = mime.lookup(data.filename);
var expire = moment().utc().add('hour', 1).toJSON("YYYY-MM-DDTHH:mm:ss Z");
var policy = JSON.stringify({
"expiration": expire,
"conditions": [
{"bucket": aws_bucket},
["starts-with", "$key", aws_bucket_dir],
{"acl": "private"},
{"success_action_status": "201"},
["starts-with", "$Content-Type", ''],
["content-length-range", 0, max_filesize]
]
});
var base64policy = new Buffer(policy).toString('base64');
var signature = crypto.createHmac('sha1', process.env.AWS_SECRET).update(base64policy).digest('base64');
signature = encodeURIComponent(signature.trim());
signature = signature.replace('%2B','+');
var file_key = uuid.v4();
res.json({ policy: base64policy,
signature: signature,
key: aws_bucket_dir + file_key + "_" + data.filename,
contentType: mime_type,
aws_access: process.env.AWS_ACCESS_KEY,
bucket_dir: aws_bucket_dir,
bucket: aws_bucket
});
});
Then on the front end I have the following code:
this.$().fileupload({
dataType: 'json',
type: 'POST',
autoUpload: true,
add: function (e, data) {
$.ajax({
url: window.ENV.api_url+'/' + window.ENV.api_namespace + '/s3',
type: 'POST',
dataType: 'json',
data: {
"filename": data.files[0].name
},
async: false,
success: function(retdata) {
//do actual upload stuff now.
data.url = 'https://'+retdata.bucket+'.s3.amazonaws.com/';
data.formData = {
key: retdata.key,
AWSAccessKeyId: retdata.aws_access,
acl: 'private',
policy: retdata.policy,
signature: retdata.signature,
success_action_status: 201,
"Content-Type": retdata.contentType
};
data.submit()
.success(function (result, textStatus, jqXHR) {
console.log('Success: ' + result);
})
.error(function (jqXHR, textStatus, errorThrown) {
console.log('Error: ' + errorThrown);
console.log(jqXHR);
console.log('Status: ' + textStatus);
});
console.log(retdata);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log('AJAX: ' + xhr);
console.log('AJAX: ' + thrownError);
}
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css(
'width',
progress + '%'
);
}
});
It seems as though I am submitting the correct form data to match my signature generation, but I am getting the following errors every time I try to submit:
SignatureDoesNotMatch - The request signature we calculated does not match the signature you provided. Check your key and signing method.
I am struggling to figure out what I might be doing wrong, if anyone can help I would appreciate it.
I struggled with this for a while and eventually got it working using the following:
in the s3 handler:
var uploadToS3 = function(s3Url, cb){
var fd = new FormData();
var file = document.getElementById('file').files[0];
var key = 'uploads\/' + file.name;
fd.append('key', 'uploads\/' + file.name);
fd.append('acl', 'public-read');
fd.append('Content-Type', 'multipart/form-data');
fd.append('AWSAccessKeyId', 'XXXX');
fd.append('policy', s3Url.s3Policy);
fd.append('signature', s3Url.s3Signature);
fd.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://XXXX.s3.amazonaws.com', true);
/////////////////////////////////////////////////////////
// Keep track of upload progress so that we can message//
// it to the user. //
/////////////////////////////////////////////////////////
var firstProgressEvent = true;
xhr.loaded = 0;
xhr.upload.addEventListener('progress', function(e) {
if (firstProgressEvent) {
firstProgressEvent = false;
}
xhr.loaded += (e.loaded - xhr.loaded);
$('progress').val((xhr.loaded / e.total) * 100);
}, false);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
if ( xhr.status >= 200 && xhr.status < 400 ) {
cb(xhr.status);
} else {
cb(xhr.status);
}
}
};
xhr.onerror = function () {
error(xhr, xhr.status);
};
xhr.send(fd);
};
});
on the server:
createS3Policy = function(key, callback) {
var date = new Date();
var s3Policy = {
"expiration": new Date(Date.now() + 300000),
"conditions": [
{"bucket": "XXX"},
["starts-with", "$key", key],
{"acl": "public-read"},
["starts-with", "$Content-Type", "multipart/form-data"],
["content-length-range", 0, 524288000]
]
};
////////////////////////////////////
// stringify and encode the policy//
////////////////////////////////////
var stringPolicy = JSON.stringify(s3Policy);
var base64Policy = Buffer(stringPolicy, "utf8").toString("base64");
////////////////////////////////////
// sign the base64 encoded policy //
////////////////////////////////////
var signature = crypto.createHmac("sha1", process.env.AWS_SECRET_ACCESS_KEY)
.update(new Buffer(base64Policy, "utf8")).digest("base64");
////////////////////////////////////
// build the results object //
////////////////////////////////////
var s3Credentials = {
s3Policy: base64Policy,
s3Signature: signature
};
callback(s3Credentials);
};
window.addEventListener("DOMContentLoaded", function() {
// Grab elements, create settings, etc.
var canvas = document.getElementById("uploader-box"),
context = canvas.getContext("2d"),
video = document.getElementById("video"),
videoObj = { "video": true },
errBack = function(error) {
console.log("Video capture error: ", error.code);
};
);
dataURL = canvas.toDataURL("image/png");
dataURL = dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
$('#some_text_area_id').val(dataURL); // set the response in text area
// jQuery('#web_image').value(image);
jQuery.ajax({
url: "/my_controller/myaction",
type: "POST",
dataType: 'jsonp',
data: 'image_data='+dataURL,
cache: false,
beforeSend:function(){
},
success: function (response_data) {
},
error: function(response_data) {
}
});
In controller file i have written
data = params[:image_data]
file_obj=File.open("#{Rails.root}/public/images/test.png","wb") do |file|
file.write(Base64.decode64(params[:image_data]))
It gives
Errno::EACCES (Permission denied - test.png):
This error please some one help me. If any another way to save canvas data in ruby please tell me
Thanks,
I have this following snippet for uploading files via Ajax post (using Knockout js library)
ko.bindingHandlers.fileUpload = {
init: function (element, valueAccessor) {
$(element).after('<div class="progress"><div class="bar"></div><div class="percent">0%</div></div><div class="progressError"></div>');
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var options = ko.utils.unwrapObservable(valueAccessor()),
property = ko.utils.unwrapObservable(options.property),
url = ko.utils.unwrapObservable(options.url);
if (property && url) {
$(element).change(function () {
if (element.files.length) {
var $this = $(this),
fileName = $this.val();
alert(fileName);
// this uses jquery.form.js plugin
$(element.form).ajaxSubmit({
url: url, //WEB API URL
type: "POST",
dataType: "text", //I want to upload .doc / excell files
headers: { "Content-Disposition": "attachment; filename=" + fileName },
beforeSubmit: function () {
$(".progress").show();
$(".progressError").hide();
$(".bar").width("0%")
$(".percent").html("0%");
},
uploadProgress: function (event, position, total, percentComplete) {
var percentVal = percentComplete + "%";
$(".bar").width(percentVal)
$(".percent").html(percentVal);
},
success: function (data) {
$(".progress").hide();
$(".progressError").hide();
// set viewModel property to filename
bindingContext.$data[property](data);
},
error: function (jqXHR, textStatus, errorThrown) {
$(".progress").hide();
$("div.progressError").html(jqXHR.responseText);
}
});
}
});
}
}
}
now my problem is creating the WEB API for this.
$(element.form).ajaxSubmit({
url: url, //WEB API URL
type: "POST",
dataType: "text", //I want to upload .doc / excell files
headers: { "Content-Disposition": "attachment; filename=" + fileName },
I want to upload Word/Excell document. Can someone give me an idea how to get this done in ASP.NET WEB API?
UPDATE:
I finally made an WEB API for this
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> PostFormData()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{
Trace.WriteLine(file.Headers.ContentDisposition.FileName);
Trace.WriteLine("Server file path: " + file.LocalFileName);
}
return Request.CreateResponse(HttpStatusCode.OK);
//return new HttpResponseMessage()
//{
// Content = new StringContent("File uploaded.")
//};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
It works ok (data successfully uploaded) but the problem is, it seems like in doesnt hit this section after the data is succesfully uploaded.
success: function (data) {
$(".progress").hide();
$(".progressError").hide();
// set viewModel property to filename
bindingContext.$data[property](data);
},
I have to inform the client of what the status of the upload.