Nodejs handles file upload
In Express4, req.files has been undefined ; the most used one now may be formidable . You know that it has a progress event, so you are overjoyed. The progress bar of the lower version of IE is a chance; OK, try it:
form .on('error',function(err){ console.log(err); }) .on('aborted',function(){ console.log('aborted'); }) .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(bytesReceived/bytesExpected).toFixed(2)*100); console.log(n); });Yes, you're glad to see that the console prints a string of progress values as expected; then, go further;
form .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(bytesReceived/bytesExpected).toFixed(2)*100); res.write('<script>window.parent.call('+n+')</script>'); //Upload without refresh, console.log(n); }); call method is to display the progress value on the page; unfortunately, you can only see the last 100%, and you cannot see the specific detailed progress value uploaded; explore again...
Next, let’s change the idea, try it, save the progress value to session , and add an additional request to poll the progress value. Oh, it’s not bad! In order to ensure that the progress value you request is the progress value you upload this time rather than the progress value of other uploads, you need to agree a token value in the uploaded request and in the additional request; now another question is how to get this token when requesting. Since the request body of the file upload is in Request Payload , req.body cannot get the value brought by it, and I don’t want to parse this pile, of course I can’t parse it either; it’s best to put it in url , the problem is that sometimes you have to refresh twice to refresh token , which is not good! As a last resort, I'll put it in cookie !
var cookies=function () { var cks=req.headers.cookie.split(';'),obj={}; for(var i=0;i<cks.length;i++){ obj[cks[i].split('=')[0].replace(//s+/ig,'')]=unescape(cks[i].split('=')[1]); } return obj; }(); var queryToken=cookies.__token__; form .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(form.bytesReceived/form.bytesExpected).toFixed(2)*100); if (req.session['file'+queryToken]) { req.session['file'+queryToken].percent=n; }else{ req.session['file'+queryToken]={ token:queryToken, percent:n } }; console.log(n); });For IE789, I came to poll for the progress value. I forgive me, but my heart hurts;
var getData=function(){ $.post('/uploader',{ getfileinfo:1, uploadtoken:utils.cookie.getCookie('__token__') }) .then(function(data){ console.log(data); if (data.mes<0) { getData(); }else{ var pros=data.info; call(pros.percent); if (pros.percent!='100') { getData(); }; }; }); } getData(); call method is to display the progress value on the page; unfortunately, you can only see the last 100%, and you cannot see the specific detailed progress value uploaded; explore again...
Okay, I fell into it again; but I still feel something is wrong, there is no problem with ajax polling. The problem is that session has to wait until the upload is completed before it has a value, so I can only see 100%, and I can't see the detailed progress value; can I think that in progress, the previous res.write and this req.session were suspended, but it saves the results of each execution until progress is released, so I can only see 100%; I am not in the mood to read the source code of formidable , of course I can't understand it, so I think so first!
Since ajax polling is fine, it is not easy to save it to session . If it really doesn't work, try it in global . It won't be able to stuff a value into the global object and it will hang it. If it makes a slight change, it will be put into global :
form .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(form.bytesReceived/form.bytesExpected).toFixed(2)*100); if (global['file'+queryToken]) { global['file'+queryToken].percent=n; }else{ global['file'+queryToken]={ token:queryToken, percent:n } }; console.log(n); });Continue polling.
Beautiful, that's all! What I see in Chrome is the same as the progress of HTML5, but it will feel a little stuck in IE789, but you can still see the detailed progress value; after all, old browsers are not good, you know; and, every time you upload, you put the value into global , so you have to clean it up appropriately. After the file is uploaded, you can transfer it to the specified directory global['file'+queryToken]=null ;
However, polling means many requests one after another, and there may be problems here; if you don’t limit it, the progress value is requested once every 500ms interval; Well, the IE789 progress bar is solved like this, and it is agreed to throw away flash; although this polling is compatible with all browsers, it is still a waste of so many requests. Let’s make a judgment, continue HTML5 outside of IE789!
Actually, if you measure it, which one is more worthy, plus one flash upload or extra request? Forgive me for not understanding flash, I won’t say much. Anyway, I don’t like to add extra files to the page;
Summarize
There are still many details about the file upload components. I originally wanted to make a JS file, but later I thought that in order to be more reusable, it would be better to do it as an independent page. If you need to upload it, just iframe it, which is definitely much better than making a JS file. The above is the entire content of this article. I hope it can help you in your study or work. If you have any questions, you can leave a message to communicate.