【问题标题】:Chrome FileReaderChrome 文件阅读器
【发布时间】:2011-05-05 07:05:36
【问题描述】:

谁能给我一个使用 FileReader API 在 chrome 中获取文件内容的示例?

它似乎为我返回了undefined

<!doctype html>
<html>
<script>
function handle_files(files) {
  console.log(files)
  reader = new FileReader()
  ret = []
  for (i = 0; i < files.length; i++) {
    file = files[i]
    console.log(file)
    text = reader.readAsText(file) //readAsdataURL
    console.log(text) //undefined
    ret.push(text)
  }
  console.log(ret) // [undefined]

}
</script>
<body>
FileReader Test
<input type="file" onchange="handle_files(this.files)">
</body>
</html>

【问题讨论】:

  • reader.readAsText(file) 是一个异步操作。您需要一个事件处理程序来处理将包含结果文本的 onload 事件。 reader.onload = function(data){console.log(data.target.result);} 循环不起作用。

标签: javascript html google-chrome filereader


【解决方案1】:

我的问题是我认为 FileReader 是同步的。 这是正确的方法。 如果您使用的是 chrome,则此代码必须在服务器(本地主机或站点)上运行。它不适用于本地文件。

<!doctype html>
<html>
<script>
function handle_files(files) {
  for (i = 0; i < files.length; i++) {
    file = files[i]
    console.log(file)
    var reader = new FileReader()
    ret = []
    reader.onload = function(e) {
      console.log(e.target.result)
    }
    reader.onerror = function(stuff) {
      console.log("error", stuff)
      console.log (stuff.getMessage())
    }
    reader.readAsText(file) //readAsdataURL
  }

}
</script>
<body>
FileReader that works!
<input type="file" multiple onchange="handle_files(this.files)">
</body>
</html>

【讨论】:

  • 你知道这是否仍然不能用于本地文件吗?我今天(2011 年 6 月 6 日)无法让它工作,但找不到任何关于此的文档...
  • @Laurie Young 它仍然无法处理本地文件,因为 Chrome 将它们视为具有不同的原点(有关详细信息和说明,请参阅 code.google.com/p/chromium/issues/detail?id=47416blog.chromium.org/2008/12/…)。如您所见,您可以在某些版本的 Chrome 上使用 --allow-file-access-from-files 开关。对我来说,它适用于 Chromium 12.0.742.112 但不适用于 Chrome。
  • 2011 年 12 月仍然适用于 Chrome 16。令人高兴的是,FF 8 运行良好。在 OS X Lion 上进行测试。
  • 正如 Jeff 提到的,--allow-file-access-from-files 将使此代码在带有本地文件的 chrome 上工作。刚刚使用 Chrome 18.0.1025.168 进行了测试。工作正常。
  • 这是一种古怪的 API,但是,嘿,它有效。好东西。
【解决方案2】:

File API FileReader 对象在 Chrome 中的运行方式与在 FireFox、Opera 或 Internet Explorer 10 中的运行方式相同(是的,works in IE)。

简单示例

您首先声明一个新的阅读器实例:

var reader = new FileReader();

为它的各种events定义你的回调:

reader.onloadend = function(){
    document.body.style.backgroundImage = "url(" + this.result + ")";
}

然后传递给它阅读:

reader.readAsDataURL(file);

小提琴:http://jsfiddle.net/jonathansampson/K3A9r/

处理多个文件

当您处理多个文件时,情况会有所不同。虽然很明显我们需要循环遍历生成的 FileList,但我们还需要使用闭包来防止文件数据在多次迭代中被篡改:

    // Continue only if we have proper support
    if ( window.FileReader ) {

      // Provide our logic upon the change even of our input
      document.getElementById("collection").onchange = function(){

        // Couple variables for handling each file
        var counter = -1, file;

        // Cycle over all files
        while ( file = this.files[ ++counter ] ) {

          // Create a reader for this particular file
          var reader = new FileReader();

          // Respond to the onloadend event of the reader
          reader.onloadend = (function(file){
            return function(){
              var image = new Image();
              image.height = 100;
              image.title = file.name;
              image.src = /^image/.test(file.type) ? this.result : "t9QlH.png";
              document.body.appendChild( image );
            }
          })(file);

          // Begin reading data for this file
          reader.readAsDataURL( file );
        }
      }
    }​

小提琴:http://jsfiddle.net/jonathansampson/jPTV3/

特征检测

尽管几乎所有现代浏览器都可以使用 FileReader,但您仍然需要确保不会对使用旧浏览器的用户造成任何骚动。在使用 FileReader 之前,请务必检查窗口对象是否存在:

if ( window.FileReader ) {
    // Safe to use FileReader
}

从 Chrome 本地运行

我应该注意,在 Chrome 中的 file:/// 路径中运行它会导致体验不佳。默认情况下,当前版本的 Chrome 不允许 file:/// 页面访问其他文件。您可以使用 --allow-file-access-from-files 标志更改此加载 Chrome 的行为。

请注意,此方法仅允许对打开它的浏览器实例上的文件进行文件访问。如果您希望将来所有浏览器实例都是这种情况,您可以从桌面修改快捷方式。只需右键单击 Chrome 快捷方式,然后转到属性。接下来,将标志添加到目标的末尾。

【讨论】:

  • 我在小提琴中尝试了您的示例,但在本地主机上的文件中它不起作用!?
  • @Alex 您需要从服务器运行它。 Chrome 中存在一个源策略,它会阻止您在本地文件中使用它。如果您必须在本地使用它,您可以使用 --allow-file-access-from-files flag 加载 Chrome。
  • @Sampson 这不是真的。它现在在客户端JS代码上对我来说有效(不是readAsDataURL(),OP的readAsText()方法),在ChromiumVersion 62.0.3202.94 (Official Build) Built on Ubuntu , running on Ubuntu 16.04 (64-bit)和chrome中。我遇到的唯一(大)问题是它在 Chrome 移动设备上不起作用,我的意思是上传似乎可以正常工作,但是我对文件完整性的测试(一个小 json)失败了:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多