如何在反应`<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 制作的简单购物应用。我在某个页面上有一个表单,我可以在其中将新产品添加到数据库中。
在那里我可以提供名称、描述、类别并上传产品图片。
问题是当我通过<input ="file">
上传图像时,我想在按下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."
,所以看起来你根本不需要路径。 <input>
的返回应该给你文件数据
实际上,我需要文件路径,以便我可以对我的服务器进行 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 上传文件,同一个文件第二次上传无反应