如何在反应`<input =“file”/>`中获取图像的绝对路径并将其存储在本地状态中?

Posted

技术标签:

【中文标题】如何在反应`<input =“file”/>`中获取图像的绝对路径并将其存储在本地状态中?【英文标题】:How to get absolute path of image in react `<input ="file" />` and store it in local state? 【发布时间】:2021-07-28 12:03:49 【问题描述】:

我有一个使用 react、react-router 和 bootstrap 制作的简单购物应用。我在某个页面上有一个表单,我可以在其中将新产品添加到数据库中。

在那里我可以提供名称、描述、类别并上传产品图片。

问题是当我通过&lt;input ="file"&gt; 上传图像时,我想在按下open 时以某种方式获取图像的绝对路径并将其存储在本地状态中。

到现在我的代码是这样的……

function Form() 
  const [imageUrl, setImageUrl] = useState("");

  // ... a bunch of code here

  return (
    <form style=styles.form>

      // ... a bunch of code here

      <div className="form-group">
        <label htmlFor="image" className="form-label" style=styles.label>
          Picture
        </label>
        <input className="form-control" type="file" id="image" required />
      </div>

      // ... a bunch of code here

    </form>
  )

我尝试过this,但这是针对 Jquery 的。

我是 React 新手,所以请善待,并在此先感谢 :)

【问题讨论】:

您是否阅读了您链接的问题中的答案?首先,有一个没有任何 jQuery 的答案(对于 Firefox)。其次,它明确指出这是不可能的。 就像许多其他人已经说过的那样,您无法获取路径,您可以获得的最好的是一个 fileHandle 引用,如果您使用新的本机文件系统访问 api(主要是仅在 chrome atm 中可用) 【参考方案1】:

由于安全原因,您无法获取完整路径。您可以尝试使用fs-js 模块来处理文件https://www.npmjs.com/package/fs-js

【讨论】:

【参考方案2】:

简答;你不能。

出于安全原因,input 文件元素会故意隐藏完整路径:

字符串以C:\fakepath为前缀,防止恶意软件猜测用户的文件结构。 (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file)

一般来说,当你使用文件输入时,就是上传文件;你根本不需要路径。

编辑例如上传到 Google 云端硬盘

注意:这需要您进行身份验证

假设你的 html 是这样的:

<form id="load-image-form">
    <input type="file" id="chosen-image" accept=".jpg,.png">
    <button type="submit">Upload</button>
</form>

那么您上传文件的脚本将如下所示:

const fileInput = document.getElementById('chosen-image')
document.getElementById('load-image-form').addEventListener('submit', e => 
    e.preventDefault();

    // check if there's any actual files chosen
    if (fileInput.files.length == 0) 
        console.log(`No files chosen`);
        return;
    

    // assume only one file - read it, and when it's ready, upload to google drive
    const file = fileInput.files[0];
    const reader = new FileReader();
    reader.onload = () => 
        console.log(`File loaded locally - uploading`)
        fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=media', 
            method: 'POST',
            headers: 
                'Content-Type': file.type,
                'Content-Length': file.size
            ,
            body: reader.result
        )
        .then(data => data.json())
        .then(console.log)
        .catch(console.error)
    
    reader.readAsArrayBuffer(file);
)

基本上在提交表单后,检查是否选择了文件,如果是,则使用FileReader 将其加载,然后使用POST 将其加载到Google Drive

当我在本地测试时,我收到了 Authorization Login Required 错误,因此您需要为此登录。

要将其上传到您的服务器(例如 Node),请使用我在评论中发布的链接:https://***.com/a/15773267/639441

【讨论】:

谢谢,我只是想要完整的路径,以便我可以使用 google drive API 上传图像。还有其他方法吗? 快速查看developers.google.com/drive/api/v3/manage-uploads#simple,你有步骤"Add the file's data to the request body.",所以看起来你根本不需要路径。 &lt;input&gt; 的返回应该给你文件数据 实际上,我需要文件路径,以便我可以对我的服务器进行 API 调用并将其传递到请求的正文中。然后服务器可以使用带有节点fs核心模块的绝对路径读取文件的内容,并创建一个流并将其上传到谷歌驱动器。 有没有办法在客户端获取file data?请帮忙。 您在示例中使用 FileReader 上传文件的方式是不必要地使用 RAM,您可以将 FileReader 全部丢弃,只使用文件作为正文 method: 'POST', body: file【参考方案3】:

您必须在 输入标签 中添加一个 onChange 函数,因此虽然您将触发同一事件的 onChange,但在该事件上您将获得目标文件路径,如下所示 (event.target.files[0]),您必须将其包装到 URL.createObjectURL 中。 因此,对于上面的代码,您必须添加以下内容,这将起作用:-

function Form() 
  const [imageUrl, setImageUrl] = useState("");
const fileBrowseHandler = (event) => 
        let value = URL.createObjectURL(event.target.files[0]);
        setImageUrl(value]);
    ;

  return (
    <form style=styles.form>
      <div className="form-group">
        <label htmlFor="image" className="form-label" style=styles.label>
          Picture
        </label>
        <input className="form-control" type="file" id="image"  onChange=fileBrowseHandler required />
      </div>

      // ... a bunch of code here

    </form>
  )

【讨论】:

以上是关于如何在反应`<input =“file”/>`中获取图像的绝对路径并将其存储在本地状态中?的主要内容,如果未能解决你的问题,请参考以下文章

input type=file 上传文件,同一个文件第二次上传无反应

js 清空html input file的值

如何自定义 <input type="file">?

如何使用 <input type="file"/> 在本地机器上模拟真实的文件上传时间?

如何重置 <input type = "file">

如何使 <input type="file"/> 只接受这些类型?