web端用js读取文件路径上传的实现方法


大家都知道,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});
            }
        });
    }
};

 

点击上传按钮:打开调试控制台,文件已经成功上传了

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM