how many times does 'progressEvents' take place during ajax file uploading? - javascript

I was new with ajax uploading , i want to add a progress bar during the uploading process.
i add a register function of progressEvent , but turns out the function only execute one time.so my progress bar will not usefull .
below is my code ,what 's wrong with my code ? what should i do the right way?thanks!
var fileEle = document.querySelector('#file');
file.onchange = function(e){
let file = e.target.files[0];
var formData = new FormData();
formData.append('book',file);
var xhr = new XMLHttpRequest();
xhr.onprogress = function(e){
console.log(e);//this only execute once ,why?
}
xhr.open('post','http://127.0.0.1:8080/profile');
xhr.send(formData);
}

in fact , the progressEvent will emit for many times.
you should register the xhr.upload object
below is the correct code:
var fileEle = document.querySelector('#file');
file.onchange = function(e){
let file = e.target.files[0];
var formData = new FormData();
formData.append('book',file);
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e){
console.log(e);//this only execute once ,why?
}
xhr.open('post','http://127.0.0.1:8080/profile');
xhr.send(formData);
}

Related

Problem with link to file, javascript, xml, object FormData

I have a function that allows you to select an attachment, but I can't get the file paths from it to send it to php.
Can it be done without using forms and reloading the entire page?
I update my function, but they return: from=s#p.pl&temat=da&msg=da&usser=lalala&file=[object FormData]
What I can do with it? I need link to file.
Function like this:
function create_form(){
var add= document.createElement("div");
add.id = "form";
var file = document.createElement("input");
file.type = "file";
file.id = "file";
var btn = document.createElement("button");
btn.id = "send";
btn.setAttribute("onclick", "send_email()");
add.appendChild(file);
add.appendChild(btn);
placeholder.appendChild(add);}
function send_email(){
php(url, params);
Function to comunication with php:
async function php(name, params, ofset){
var params = params;
if(document.getElementById("file")){
var plik = document.getElementById("file");
var file = plik.files[0];
var fd = new FormData();
fd.append("file", file);
params += '&file=' + fd;}
let http = XML();
let odp = "420 - error php function";
if(typeof ofset == 'undefined'){
var ofset = 100;}
http.onreadystatechange=function(){
if (http.readyState==4 && http.status==200)
{
odp = JSON.parse(this.responseText);
}}
var url = name;
http.open('POST', url, true);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.send(params)
let promise = new Promise((resolve, reject) => {setTimeout(() => resolve(odp), ofset)});
let result = await promise;
return result;}
It looks to me like you're using FormData incorrectly here. If you take a look at this part of your code:
var fd = new FormData();
fd.append("file", file);
params += '&file=' + fd;
Unless you serialize them somehow, binary files can't be uploaded as URL parameters, they have to be sent as part of the request body. I think you're close, and there's just two changes you need to make here:
First, your URL parameters need to be tacked onto the URL itself:
var url = `${name}?${params}`;
You then need to pass your FormData into send():
var fd = new FormData();
fd.append("file", file);
}
...
http.send(fd);
If you need some more help using FormData, check the MDN docs.

Read the excel file from the specific location

I don't want to use this way(link)
because I don't want to open new window for file selection.
I just want to load & read excel file when I click some button.
But this is not work.. help me to load the excel file.
MYCODE:
const FILE_NAME = "C:/Users/A/project_list.xlsx";
function LoadSpread(json) {
jsonData = json;
workbook.fromJSON(json);
workbook.setActiveSheet("Revenues (Sales)");
}
function excelExport(fileName) {
console.log(fileName);
var excelUrl = fileName;
var oReq = new XMLHttpRequest();
oReq.open("get", excelUrl, true);
oReq.responseType = "blob";
oReq.onload = function() {
var blob = oReq.response;
excelIO.open(blob, LoadSpread, function(message) {
console.log(message);
});
};
oReq.send(null);
}
function chkPrtNum(event) {
var fileName = FILE_NAME;
excelExport(fileName);
}
Try creating a small server for the same, you will easily get your job done. – Raghu Chahar Jan 28 at 9:50
This was very helpful

InboxSDK - Unable to attachFiles through composeView object

I am trying to attach an attachment through the composeView object using Inboxsdk. I obtain a blob object from a remote url using the following code.
// FUNCTION TO OPEN A NEW COMPOSE BOX ONCE THE ATTACHMENT BLOB IS OBTAINED FROM REMOTE URL.
function openComposeBox(sdk, blob){
handler = sdk.Compose.registerComposeViewHandler(function(composeView){
if(blob != null){
composeView.attachFiles([blob]);
composeView.setSubject("Testing");
}
});
}
// FETCHING ATTACHMENT FILE FROM REMOTE URL
var file_btn_url = "https://api.hummingbill.com/system/invoices/invoice_files/000/033/393/original/abracadabra.txt";
var file_name = file_btn_url.split("/");
file_name = file_name[file_name.length-1];
file_type = /[^.]+$/.exec(file_name);
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", file_btn_url);
xhr.responseType = "blob";
xhr.onload = function()
{
blob = xhr.response;
// blob.lastModifiedDate = new Date(); // Since it's not necessary to have it assigned, hence commented.
blob.name = file_name;
console.log(blob);
openComposeBox(sdk, blob);
}
xhr.send();
It shows an Attachment Failed error.
Although I have the correct format of blob object as required as per the documentation.
As per the documentation, I have set the filename for the blob, and passed it in an array to attachFiles function. Can you please look into it and let me know what am I missing?
Posting the solution. The code remains same as in the question, with a slight variation, wherein we convert the blob to a file, in order to make it work.
//... Same as the code in the question
// Fetching attachment file from remote url
var file_btn_url = "https://api.hummingbill.com/system/invoices/invoice_files/000/033/393/original/abracadabra.txt";
var file_name = file_btn_url.split("/");
file_name = file_name[file_name.length-1];
file_type = /[^.]+$/.exec(file_name);
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", file_btn_url);
xhr.responseType = "blob";
xhr.onload = function()
{
// Solution: Convert the obtained blob to a file
// Pass the file to openComposeBox
blob = new Blob([xhr.response], { type: xhr.responseType });
var file = new File([blob], file_name);
blob.name = file_name;
openComposeBox(sdk, file);
}
xhr.send();
Hope this helps. Cheers!

XMLHttpRequest on load in saveback to calling object

I'm trying to load in many json files for a HTML5 game that will serve as sprite sheets. Previously I've did this synchronously but my new goal is to do this asynchronously.
I have run into a problem though where I'm trying to saving back to the calling object. This is so the information loaded can be used later and so a flag (loaded) can be set so the system knows when a resource has been loaded. Below is my XMLHttpRequest code. I have substituted "spritesheet" for what ever the call should be to save back to the parent.
function SpriteSheet(filename)
{
var tmpFileName = "json/" + filename;
this.loaded = false;
var xhr = new XMLHttpRequest();
xhr.open("GET",tmpFileName,true);
xhr.onload = function(event){
var parsed = JSON.parse(this.responseText);
"spritesheet".img=new Image();
"spritesheet".img.src = "imgs/" + parsed["imgLoc"];
"spritesheet".animations = parsed["animations"];
"spritesheet".sprites = parsed["sprites"];
"spritesheet".loaded = true;
};
xhr.send();
}
Can somebody inform me how I can save back to the the parent or if this is completely the wrong approach can they point me in the direction of a solution.
I found that by creating a var in the 'class' that is a reference to the object and using it in the onload function works, for example:
function SpriteSheet(filename)
{
var tmpFileName = "json/" + filename;
this.loaded = false;
var caller = this;
var xhr = new XMLHttpRequest();
xhr.open("GET",tmpFileName,true);
xhr.onload = function(event){
var parsed = JSON.parse(this.responseText);
caller.img=new Image();
caller.img.src = "imgs/" + parsed["imgLoc"];
caller.animations = parsed["animations"];
caller.sprites = parsed["sprites"];
caller.loaded = true;
};
xhr.send();
}

How to I refer to the `postMessage()` function from my XHR callbacks?

The file uploads work perfectly, I can't get the progess and load events to callback
I have the following in a JavaScript file as my WebWorker code:
UploadFileWorker.js
function uploadFile(url, m) {
var f = m.file;
var fd = new FormData();
fd.append('file', f, f.name);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function (e) {
m.set('status', (e.loaded / e.total) * 100 );
postMessage(m); // <-- never makes the call, doesn't throw and error either
});
xhr.upload.addEventListener('load', function (e) {
m.set('status',100);
postMessage(m); // <-- never makes the call, doesn't throw and error either
});
xhr.open('POST', url, true);
xhr.send(fd);
}
function getUploadURL(m) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function () {
var url = this.responseText;
uploadFile(url,m);
});
xhr.open('GET', '/upload', false);
xhr.send();
}
var q = [];
onmessage = function(e) {
postMessage(e.data);
q.push(e.data);
while (q.length > 0) {
var m = q.pop();
getUploadURL(m);
}
};
The postMessage(e.data); in the onmessage function work perfectly.
The postMessage(m); in the xhr.upload.addEventListeners() callbacks never happen. They worked fine before I tried and move these functions into WebWorker code.
Is this a scope issue? If so, how do I prefix the calls to get them to work.?
For completeness here is how I am defining my instance of Worker and kicking it off.
onButtonClick: function(button, e, eOpts) {
var ugv = this.getUploadGridView();
var fs = this.getFileUploadStore();
var worker = new Worker('/js/UploadFileWorker.js');
worker.onmessage = function(e) {
console.log(e);
};
var selected = ugv.getSelectionModel().getSelection();
Ext.each(selected, function(m) {
var o = {};
o.name = m.get('name');
o.size = m.get('size');
o.status = m.get('status');
o.file = m.file;
worker.postMessage(o);
});
},
Again the actual uploading of the files works great, I can't figure out how to call postMessage(); from inside the xhr callbacks.
This is apparently a bug that has been fixed just recently.
Issue 71433002: Enable XHR upload progress events for Workers. (Closed)
Workaround until Chrome gets updated
xhr.addEventListener(
instead of
xhr.upload.addEventListener(
This has the drawback that progress only gets called for every 1MB, files smaller than 1MB never get a progress event fired.

Categories

Resources