Javascript 将文件内容传递给外部变量

Javascript 将文件内容传递给外部变量,javascript,filereader,Javascript,Filereader,我正在使用文件阅读器和HTML文件对话框来读取脚本中的文件。如何从FileReader.onload函数中传递此文件的内容 function readFileData(evt) { var file = evt.target.files[0]; var reader = new FileReader(); reader.onload = function(e) { var contents = e.target.result; } reader.readAsText

我正在使用文件阅读器和HTML文件对话框来读取脚本中的文件。如何从FileReader.onload函数中传递此文件的内容

function readFileData(evt) {
  var file = evt.target.files[0];
  var reader = new FileReader();

  reader.onload = function(e) {
    var contents = e.target.result;
  }
  reader.readAsText(file);
}
document.getElementById('file').addEventListener
    ('change', readFileData, false);

/* I want to access the contents here */

我尝试在readFileData和onload函数中粘贴返回值,但我不确定它们返回的是什么。

我假设您知道,它是异步的

因此,简单的回答是:不,你不能那样做

但是,如果您希望将来的任何呼叫都可以全局访问内容,您可以这样做:-

var contents;// declared `contents` outside
function readFileData(evt) {
  var file = evt.target.files[0];
  var reader = new FileReader();

  reader.onload = function(e) {
    contents = e.target.result; //<-- I removed the `var` keyword
  }
  reader.readAsText(file);
}

document.getElementById('file').addEventListener('change', readFileData, false);

var reasonableTimeToWaitForFileToLoad = 100000;

console.log(contents); //`contents` access first attempt: prints undefined



setTimeout(function() {
  console.log(contents);//`contents` access second attempt: prints the contents 'may be if the time allows.'
}, reasonableTimeToWaitForFileToLoad);
var内容;//在外部声明“内容”
函数readFileData(evt){
var file=evt.target.files[0];
var reader=new FileReader();
reader.onload=函数(e){

contents=e.target.result;//这是一个范围问题。当您在onload中声明内容时,该函数运行后将不再可用。您需要首先声明该范围之外的内容

var contents;
function readFileData(evt) {
  var file = evt.target.files[0];
  var reader = new FileReader();

  reader.onload = function(e) {
   contents = e.target.result;
  }
  reader.readAsText(file);
}
document.getElementById('file').addEventListener
    ('change', readFileData, false);

//make changes here
//contents should have the correct value

首先,您必须认识到,使用
FileReader
读取文件是一项异步任务,您无法以同步方式使用它

有很多方法可以解决这个问题,但其中很多不适合推荐;)

我会采用以下两种方式之一:

1:您可以从onload事件处理程序中调用函数,并将文件内容作为参数传递


2:您可以从onload事件处理程序中触发事件,并将文件内容作为事件数据传递

只需在两个函数外部声明
内容
,并在内部函数内部分配:

var contents;
var outer_fn = function() {
  var inner_fn = function() {
    contents = '42';
  }
  inner_fn();
}
outer_fn();
// here, `contents' is '42'

我面临着类似的挑战,这就是我用来解决这个问题的方法

var contents;
function readFileData(evt) {
  var file = evt.target.files[0];
  var reader = new FileReader();

  reader.onload = function(e) {
   contents = e.target.result;
  }

 reader.readAsText(file);

 //calling to access the 'contents' variable
 accessFileContents();
}  

document.getElementById('file').addEventListener('change', readFileData, false);
var wait4file2load = 1000;

/* To access 'contents' here */
function accessFileContents(){
  setTimeout(function(){
    console.log(contents);
  }, wait4file2load);
}

它不会给出未定义的值,因为我们在文件完全上传后调用它。

我在Angular 7(typescript)中遇到了类似的问题,这就是我解决问题的方法

var contents;
function readFileData(evt) {
  var file = evt.target.files[0];
  var reader = new FileReader();

  reader.onload = function(e) {
   contents = e.target.result;
  }

 reader.readAsText(file);

 reader.onloadend=function(e) {
   console.log(contents)
 }
}  

document.getElementById('file').addEventListener('change', readFileData, false);    
我想做的是访问fileReader->reader.onload中发生的base64转换

然后将该参数传递给另一个方法,在该方法中,我可以将其转换为JSON对象,然后将其发布到API,因为我希望在post中也发布另一个参数

我首先要做的是声明在该方法之外可能需要访问的内容

base: any = null;
base64File: any = null;
fileToTest: any = null;
然后,当upload事件触发时,我将pdf转换为base64


convertToBase64 (e){

  this.fileToTest = e.target.files[0];
  var reader = new FileReader();
      reader.onload = () => { 
        this.base64File = reader.result.slice(28); 
};

reader.onerror = function (error) {
  console.log('Error: ', error);

}.bind(this.base64File);

reader.readAsDataURL(this.fileToTest);

return this.base64File;
}

最后用另一种方法访问base64文件


 onSubmit() {

  console.log("base 64 file is visible", this.base64File);

    var base = 
      {
        "FileBase64": this.base64File,
        "Path": "document",
        "FileType": ".pdf"
      };

  console.log("JSON object visible", base);
  this.uploadService.base64Post(base);
}   
现在一切都正常了,希望这能帮助其他人发现自己也有同样的问题


使用Angular 7,代码在组件文件中,post函数在服务文件中。如果没有我的注释,代码在组件文件中与此完全相同。

您想访问注释中的内容吗?@Musa:您是真的这样解释问题,还是只是一个混蛋?有没有办法确定fi什么时候le已加载?用户将上载大小不一的大文件,可能需要一段时间才能加载。我是否应该等待内容未通过循环定义?不,不要这样做。Javascript是单线程的。因此,该循环将永远运行,直到浏览器崩溃。现在,知道文件已加载的唯一方法是
reader.onload=function(e) {/**here**/}
。您可以递归地使用
setTimeout
检查文件是否已加载。但是,在我看来,
setTimeout
是过时的。请设计能够对事件做出反应的代码。您会做得很好。您必须解释您的答案。由于文件读取器是异步的,这绝对不起作用。