【问题标题】:JS Multiple file upload returns last file of loopJS多文件上传返回循环的最后一个文件
【发布时间】:2018-02-21 13:25:38
【问题描述】:

我正在尝试在 JS 中进行多个文件上传。

我在 html 中有这个输入

 <input type="file" (change)="fileChange($event,showFileNames)" multiple />

然后对于 onChange 事件执行

this.files = [].slice.call(event.target.files);
input.value = this.files;

This.files 包含要上传的文件数组。

然后在按下 "SUBMIT" 之后,这就是我想要做的。此代码取自先前类似线程的答案,但我仍然没有运气。

upload() {
    for (var i = 0; i < this.files.length; i++) { //for multiple files       
         var that = this;
         (function (file) {   
             var name = file.name;
             var reader = new FileReader();

             let parts = file.name.split(".");
             that.filename = parts[0];

             if (typeof (parts[1]) != "undefined")
                  that.ext = "." + parts[1];
             else
                  that.ext = "";

             reader.onload = function (e) {
                 var x = this.result;
                 let fileJSON = { "Filename": that.filename, "Extension": that.ext, "DateCreated": new Date(), "Data": btoa(this.result), "Sguid": that.tripsToEditx.sguid };
                 console.log(fileJSON);
             }
             reader.readAsArrayBuffer(file);
        })(this.files[i]);
    }
}

变量名、ext 和 tripsToEditx 是全局变量,我无法通过 .this 访问它们,所以我使用了

var that = this;

无论如何,我仍然要打印 3 次最后选择的文件。

有什么解决办法吗?

【问题讨论】:

  • that.filename = parts[0]; 如果这是全局的,您将多次打印同一个文件,因为您在这里有异步代码。为什么不直接使用 parts[0] 作为闭包的一部分。
  • 哇,不知道我怎么错过了。现在名称和扩展名有效,但数据对所有人都是一样的。关于如何解决这个问题的任何想法?
  • 你不能只在 ArrayBuffer 上做一个btoa,但你可以在一个视图上做一个。我会发布一个 sn-p 作为例子。

标签: javascript file typescript upload


【解决方案1】:

btoa,在 ArrayBuffer 上并没有达到您的预期,.. 但它确实在 Uint8Array 上工作,所以如果我们创建 ArrayBuffer 的视图,我们就可以在此上执行 btoa。

下面是一个示例,选择一些文件,然后在浏览器控制台中查看输出。

ps。如果您可以使用letconst,则不需要使用函数闭包,因为它们会为您处理。

function arrayBufferToHex(buffer) {
  const view  = new Uint8Array( buffer );
  return Array.prototype.map.call(view, function(byte) {
    return ('0' + (byte & 0xFF).toString(16)).slice(-2);
  }).join('');
}


document.querySelector("input").onchange = function () {  
  for (let i = 0; i < this.files.length; i++) {
    const file = this.files[i];
    const reader = new FileReader();
    reader.readAsArrayBuffer(file);
    reader.onloadend = function (e) {     
      const splits = file.name.split(".");
      const fileJSON = { 
        "Filename": splits[0], 
        "Extension": splits[1], 
        "DateCreated": new Date(), 
        "Data": arrayBufferToHex(this.result), 
        "Sguid": "XYZ" };
      console.log(fileJSON);
    }
  }
}
<div>Open browser console, to see results.</div>
<br>

<input type="file" multiple />

【讨论】:

  • 使用 btoa(view) 给出错误“'Uint8Array' 类型的参数不能分配给'字符串'类型的参数。”。也许在 TS 中是不可能的?
  • @user3465096 视图上的 btoa 也不符合您的预期,.. 我刚刚做了一个快速更新..
  • 似乎有效!接受作为答案!还有一个问题,如果我需要将这个数据保存在 Postgresql 类型“Bytea”中,也许你可以告诉我这个转换是否可以?
  • @user3465096 我不是Postgresql,但hex是hex,所以如果有办法使用hex将数据插入postgresql,我看不出有问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
相关资源
最近更新 更多