【问题标题】:Prevent HTML file input from selecting files in Google Drive while using Android's native file chooser防止 HTML 文件输入在使用 Android 的本机文件选择器时选择 Google Drive 中的文件
【发布时间】:2019-12-22 07:45:51
【问题描述】:

目前我正在开发一个允许用户将文件上传到 Firebase 存储的页面。在 Android 上通过 Google Chrome 打开网站并从标准 HTML 文件输入中选择要上传的文件时,它使用 Android 的本机文件选择器。

在大多数情况下,用户会选择存储在设备本地的文件,但文件选择器也会显示他们的 Google 云端硬盘文件,并且当前不会阻止用户选择其中一个文件。该文件在 Javascript 中作为 File 对象返回,但是当尝试上传到 Firebase 存储时,它会抛出错误:“net::ERR_UPLOAD_FILE_CHANGED”并最终超过它的重试限制。

为了防止用户混淆,我想阻止用户在 Android 的文件选择器中选择 Google Drive 文件,或者至少认识到它无法上传并警告用户。

我考虑过检查输入元素返回的 File 对象,但没有任何迹象表明可以将本地文件与 Google Drive 文件区分开来。

<input type="file" id="upload_input" class="hide"/>
$("#upload_input").change(function(e) {
  if (!e.target.files) {
    return;
  }
  const file = e.target.files[0];
  uploadFile(file);
});


uploadFile(file) {

  ...

  const storageRef = firebase.storage().ref();
  const fileRef = storageRef.child(`${userID}/uploads/${file.name}`);
  const uploadTask = fileRef.put(file);

  ...

}

【问题讨论】:

  • 有什么解决办法吗?
  • 仍在寻求解决方案

标签: javascript firebase google-chrome google-drive-api firebase-storage


【解决方案1】:

我不知道阻止文件选择器显示这些文件的方法,我怀疑没有,但是您可以通过尝试读取来轻松检查您的代码是否能够将其发送到您的服务器.

我们可以尝试只读取第一个字节,而不是读取整个文件,方法是对 File 对象进行切片。然后要读取它,我们可以简单地调用它的arrayBuffer() method,它会返回一个 Promise,要么在文件有效时解析,要么在我们无法访问文件时拒绝:

const inp = document.querySelector('input');
inp.onchange = (evt) => {
  const file = inp.files[ 0 ];
  file.slice( 0, 1 ) // only the first byte
    .arrayBuffer() // try to read
    .then( () => {
      // success, we should be able to send that File
      console.log( 'should be fine' );
    } )
    .catch( (err) => {
      // error while reading
      console.log( 'failed to read' );
      inp.value = null; // remove invalid file?
    } );
};
&lt;input type="file"&gt;

请注意,即使存储在磁盘上的文件也可能被用户修改,因为他们确实在您的网站中选择了它,在这种情况下,上传仍然会失败。要处理这种情况,您只需执行完全相同的测试即可。

还要注意Blob.arrayBuffer() 是相当新的,可能需要一个polyfill,它很容易在互联网上制作或找到。

【讨论】:

  • 我可以确认这行得通!从 Google Drive 中选择的文件引发了异常,而本地文件没有。根据 API 的状态,我可以在未来看到这种变化,但现在它可以工作。有趣的是,使用 FileReader API 将 Drive 文件读入 ArrayBuffer 仍然可以无错误地提供数据。
  • @JBrewer 尝试使用 FileReader API 导致 ProgressEvent 名称 NotReadableError 消息 的另一个错误实例无法读取所请求的文件,通常是由于在获取对文件的引用后发生的权限问题。 .是的,它有时会起作用。你能确认它总是正常工作吗?
  • @Shandor Kostur - 从我之前的评论中,我并不是说 FileReader API 有效,只是您可以在本地浏览器上以编程方式访问 Google Drive 文件的原始数据,即与我们在这里想要的相反。在这种情况下,当尝试将文件上传到 Firebase 存储时,请使用答案中的方法,而不是 FileReader API。
【解决方案2】:

它处理文件修改属性。输入标签正在获取一个同名的文件,但它的修改属性没有改变。

我得到的唯一解决方案是 -

您需要重置用户输入标签的输入字段字段 默认情况下单击它会在单击时变为空。

例如;使用 jquery 库重置输入标签

   document.querySelector("#upload_input").addEventListener("click", 
    function(event){
       $("#upload_input").val("");
    })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 2012-08-15
    • 1970-01-01
    • 2011-04-29
    • 2015-11-03
    • 2018-06-18
    相关资源
    最近更新 更多