大家都知道,web端如果實現文件上傳通常的做法是利用input 標簽實現文件域,最近在用electron做了一個客戶端,我發現在electron下可以使用nodejs的fs模塊來實現上傳,特此分享下
通常的做法:
<form id="frm" method="post" enctype="multipart/form-data" action="/upload.do"> <input type="file" name="files[]" id="file_input" /> </form>
下面是用electron做的一個測試頁面,這個頁面很簡單,只有一個上傳按鈕:
<div class="uploadBtn" onclick="UploadUtil.test()" style="background:unset;margin-right: 30px; border: 1px solid #ddd;text-align:center;padding-right: 20px;"> 上傳文件 </div><!-- 上傳 -->

electron引用node模塊,可以用window.Electron.require('模塊名'),這里用到兩個模塊:fs和mime,用fs讀取文件然后再封裝成File對象再利用ajax上傳,上傳成功后會在控制台打印“上傳成功”。
File對象是Blob對象進一步封裝,具體介紹請點這里:https://developer.mozilla.org/en-US/docs/Web/API/File

以上是,File對象的構造方法,第一個就是我們要傳進去的blob對象構成的數組,第二參數是文件名,第三個參數是指定Blob屬性,因為第一個參數傳的就是blob對象,因此可以忽略
讀取文件主要用到fs的兩個api: readFile 和 createReadStream,前者是讀取一個完整的文件到內存中,后者是建立文件流的方式讀取,如果要上傳大附件用后面的方法比較好,關於這兩個方法具體的介紹我就不詳述了,畢竟官網的介紹已經很詳細了
你可以點下面的鏈接看官方文檔:https://nodejs.org/api/fs.html
關於ajax上傳相信做web開發的同學已經很熟悉用法了,有的File對象就可以直接構造FormData。
var formdata = new FormData(); formdata.append('enctype', 'multipart/form-data') formdata.append('Filedata', file);
下面我貼出完整的代碼,命名空間是個好東西,多用用,
var UploadUtil = { fs: window.Electron.require('fs'), mime: window.Electron.require('mime'), test: function(){ var path = "C:\\Users\\elvis\\Downloads\\404錯誤.log"; var uploadUri = "/upload.do"; this.readAndUpload(path, uploadUri); }, // 讀取並上傳文件 readAndUpload: function(path, uploadUri){ var _self=this; _self.getFileStats(path, function(err, stats){ if(err) return; // 讀取文件 --begin var readStream = _self.fs.createReadStream(path); var blobParts; readStream.on('open', function(fd){ blobParts = new Array(); console.log("Read \'"+path+"\' open"); }); readStream.on('data', function(data){ var blob = new Blob([data], {type: stats.type}); blobParts.push(blob); }); readStream.on('end', function(){ console.log("Read \'"+path+"\' end"); ajaxUpload(blobParts, stats); }); readStream.on('close', function(){ console.log("Read \'"+path+"\' close"); }); readStream.on('error', function(err){ console.info('[!ERR!] Read \''+path+'\' failed!'); // 讀取過程中出錯了,清空數據 blobParts.splice(0, blobParts.length); }); // 讀取文件 --end }); function ajaxUpload(blobParts, stats) { if(!blobParts || blobParts.length <= 0) return; var xhr = new XMLHttpRequest(); xhr.open("POST", uploadUri, true); // 封裝file對象 var file = new File(blobParts, stats.name); file.path = stats.path; var formdata = new FormData(); formdata.append('enctype', 'multipart/form-data') formdata.append('Filedata', file); xhr.onload = function (evt) { console.log("上傳完成"); } xhr.send(formdata); } }, // 讀取文件信息 getFileStats:function(path, callback){ var _self=this; _self.fs.stat(path, function(err, stats){ if(typeof callback != 'function') return; if(err) callback(err); else{ var index = path.lastIndexOf('\\'); var len = path.length; var filename = index != -1? path.substring(index+1, len):path; var mimetype = _self.mime.lookup(path) callback(null, {size:stats.size, name:filename, path:path, type:mimetype}); } }); } };
點擊上傳按鈕:打開調試控制台,文件已經成功上傳了

