JavaScript
如何获取用户input[type=file]
选择的文件路径呢?
首先,JavaScript
本身是无法通过input[type=file]
获取用户选择的文件路径的,这条路是行不通的。
- 有经验的都知道,这样获取到的路径是
C:/fakepath/...
一类的路径。
所以,那我们还有办法通过input[type=file]
获取文件的路径吗?
答案:有
- 写一个
C++
去调用系统底层的一些东西,然后交给JavaScript
调用这个C++
文件 - 曲线救国
C++
,我…不会写,所以还是看一下曲线救国
注意:得用node,不过现在vue,react,angualr项目,使用个node想必没得问题。
OK,我们继续:
首先,分开看问题:
- 我们要获取文件的绝对路径。
- 获取的文件是用户通过
input[type=file]
选择的文件。
这两者有关系吗?有,好像又没有:
- 有:我们需要获取的是用户选择的文件的路径
- 没有:我们需要获取的是一个文件路径,路径地址指向的文件和用户选择的文件一模一样。
所以,如果用户选择的文件,在某个我们的 项目代码 能 访问到的地址 里 有个备份 是不是就完美解决了这个问题
- 能访问到的地址:那肯定是你的项目目录了,这样你的代码都能访问到。
- 还能用
node
的path.resolve()
获取到程序所在的绝对路径目录或者将相对目录解析成绝对目录。
- 备份:那就是文件拷贝了。
文件拷贝好像是个麻烦事,而且曲线救国的曲线,也主要是在这里,大致分为以下几步:
- 首先在项目根目录创建一个
temp
临时文件夹【不用创建也行,写入文件时会自动创建】 - 获取用户通过
input[type=file]
选择的文件的file
对象,如果是多选,获取的就是一个file
对象数组. - 通过
FileReader
将file
对象,转换为一个buffer
- 利用node的文件写入方法,将
buffer
写入到我们创建出来的文件中。【这一步不明白的我后面会有解释】
文件拷贝:代码简述
- 获取用户选择的文件的
file
对象:
<input type="file" name="copy" id="copy" multiple>
// 这里强调一下:框架有框架自己的获取dom元素的方法,而且input[type=file]的change事件,在框架中其实也用不着获取dom元素,直接把input标签上绑定事件就好了。
// 这里最主要的就是获取到file对象,我这么写,只是为了做一下演示
let fileBtn = document.getElementById('copy');
fileBtn.addEventListener('change', (file) => {
let filesArr = file.target.files;
console.log(filesArr);
});
- 通过
FileReader
转换
...
fileBtn.addEventListener('change', (file) => {
let filesArr = file.target.files;
for(let i = 0; i < filesArr.length; i++) {
let fileReader = new FileReader();
fileReader.onload = () => {
// 这里输出出来的就是 buffer 对象
console.log(fileReader.result);
}
fileReader.readAsArrayBuffer(filesArr[i]);
}
});
- 将
buffer
写入到文件中。
- 这一步 node 的操作是这样,虽然我们只是简单调用了一个方法,我简单说一下:
- 创建一个空的同名文件,在我们提供的文件位置下。
- 将buffer写入到这个文件中。
有兴趣的可以去研究一下node怎么干的。
import {writeFileSync} from "fs";
...
fileReader.onload = () => {
// 通过path.resolve,将temp文件夹解析成一个绝对地址,然后拼上文件名称
writeFileSync(`${path.resolve(__dirname,'./src/temp')}/${filesArr[i].name}`, fileReader.result, (err)=>{
if(err){
console.log('文件写入失败');
return;
}
console.log('文件写入成功');
});
}
writeFileSync
是node
文件系统中的一个文件写入的同步方法,可以将buffer数据,写入到文件文件中。
这个函数接受几个参数,其中主要的:
- 文件名称,也可以是文件地址【若为文件地址,则其会为我们自动创建文件夹路径】
- buffer对象
- 回调函数
具体了解,可以看菜鸟教程的讲解,我觉得挺好的,传送门:writeFileSync方法
其实到这里,就基本可以了,简单总结一下就是:将用户选择的文件,转化到我们的项目下,因为项目下的文件可以获取其绝对地址。
至于之后,要做什么操作,操作完了,是不是要删除掉,这都看需求啦。
而且,node对文件的操作很牛,删除什么的完全不是事。
PS: 看到了下面用户的评论,这里简单说一下:
- 首先呢,这篇【曲线救国】的文章也只是我在在对js选择本地用户文件上的一个想法。
- 其次,浏览器端到不是真的用不了nodejs,比如使用bowserify进行转化。我也是看到了这点,才写了这篇文章,但具体操作,还是要个人去实践才行,若你有成功的案例,欢迎回评!
- 最后,其实想想,若你真的到了需要在浏览器中使用nodejs操作本地用户文件的地步,那说不得你的需求或逻辑出了这样或那样的问题😂,因为对用户来说这是极其不安全!