likes
comments
collection
share

如何将本地文件转成流数据传递给后端?

作者站长头像
站长
· 阅读数 16

简介

项目实际开发过程中,可能涉及文件上传的需求。前端无法直接将一个文件传递给后端,而是需要将一个文件转成流数据通过POST接口传递给后端。

那么?我如何将本地文件转换成流数据呢?

通过input标签获取数据信息

文件选取

html中,将input标签的type设置成file可以实现文件选取。

<body>
	<input type="file"  />
</body>

如何将本地文件转成流数据传递给后端?

此时,input标签还有multipleaccept两个相关属性可选。

  • multiple:每次是否可以选择多个文件
  • accept:可选择的文件类型
<body>
		<input type="file"  multiple="multiple" accept=".pdf,.png" />
</body>

如何将本地文件转成流数据传递给后端?

获取文件的数据信息

当我们选择文件后,会触发input标签上的changge事件,我们给该事件绑定我们自定义的处理事件,即可获取到选择的文件信息。如:

	<body>
		<input type="file"  multiple="multiple" accept=".pdf,.png" id="inputFile" onchange="fileChange" />
	</body>
	<script type="text/javascript">
		function fileChange(){
			let fileList = document.getElementById("inputFile").files
			console.log(fileList )
		}
	</script>

如何将本地文件转成流数据传递给后端?

我们仔细观察控制台,可以发现文件选择后,浏览器返回了一个FileList对象,这个对象是一个伪数组,包含了每个文件的File对象。

File对象

什么是File对象呢?我们先看官网的定义:

文件(File)接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。

简单来说,File是一个构造函数,我们控制台中的fileList[0] 对应的内容就是File的实例化对象。

验证下:

console.log(fileList[0].__proto__.constructor)   // ƒ File() { [native code] }

File构造函数有5个属性:

属性名属性含义
File.lastModified返回当前 File 对象所引用文件最后修改时间
File.name返回当前 File 对象所引用文件的名字
File.size返回文件的大小
File.webkitRelativePath返回 File 相关的 path 或 URL
File.type返回文件的MIME 类型developer.mozilla.org/zh-CN/docs/…
File.lastModifiedDate返回当前 File 对象所引用文件最后修改时间的 Date 对象

fileList[0] 作为File构造函数的实例化对象,自然继承以上所有属性。

function fileChange(){
      // 我们选择一个pdf文件
			let fileList = document.getElementById("inputFile").files
			console.log(fileList[0])
		}

如何将本地文件转成流数据传递给后端?

通过FileReader获取数据信息

我们可以理解为File对象是DOM接口和文件之间的一个桥梁,通过这个桥梁我们,我们拿到了文件,知道了它的名称、大小等信息。但如果我们想知道文件的具体内容是什么,就要借助其他接口实现了。

FileReader构造函数就是用来获取文件内容的。我们来看个示例:

<body>
		<input type="file"  multiple="multiple" id="inputFile" onchange="fileChange()" />
	</body>
	<script type="text/javascript">
		function fileChange(){
			//获取file对象(点击input,上传文件触发)
			let fileList = document.getElementById("inputFile").files
			//创建fileReader实例化对象
			let fileReader = new FileReader();
			//读取的文件或数据
			fileReader.readAsDataURL(fileList[0])
			//文件读取成功的回调
			fileReader.onload = function(){	
				//fileReader.result 就是文件的的内容
				console.log(fileReader.result)
			}
		}
	</script>

如何将本地文件转成流数据传递给后端?

从上述示例我们可以知道,通过fileReader的result属性,我们可以拿到文件的具体数据。我们来看看fileReader的其他属性与方法。

fileReader的属性与方法

主要的事件

事件名事件触发条件
FileReader.onabort该事件在读取操作被中断时触发。
FileReader.onerror该事件在读取操作发生错误时触发。
FileReader.onload该事件在读取操作完成时触发。
FileReader.onloadstart该事件在读取操作开始时触发。
FileReader.onloadend该事件在读取操作结束时(要么成功,要么失败)触发。
FileReader.onprogress该事件在读取文件时触发。

核心方法

方法名方法内容
FileReader.abort()中止读取操作。在返回时,readyState属性为DONE。
FileReader.readAsArrayBuffer()开始读取指定的 Blob中的内容, 一旦完成, result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.
FileReader.readAsDataURL()开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的Base64字符串以表示所读取文件的内容。
FileReader.readAsText()开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个字符串以表示所读取的文件内容。

注:这里的Blob也是一个文件属性的构造函数,File构造函数继承与Blob构造函数。File实例化对象拥有Blob上的所有属性与方法,也有一些属于自己的内置方法。

核心属性

FileReader.result

只读属性, 文件的内容。该属性仅在读取操作完成后才有效,数据的格式取决于使用FileReader.readAsDataURL() 还是FileReader.readAsArrayBuffer()

dataUrl和ArrayBuffer都是文件在计算机中的一种存储格式,本篇文章我们不展开讨论,总之,这两种格式都是可以直接传递给后端的,当然,对于多数情况下,我们传递给后端的还是ArrayBuffer

将数据发送给后端

当我们获取到数据后,将文件传递给后端是非常容易的。我们如果使用axios,发送一个接口应该是这样:

axios.post("http://192.XXXX.XXX",data).then(res =>{
		console.log(res)
})

应用到我们的文件发送代码中,应该是这样

function fileChange(){
			// .....
			fileReader.onload = function(){	
				//fileReader.result 文件的内容
				let data = {
					fileBuffer:fileReader.result
				}
				axios.post("url",data).then(res =>{
					console.log(res)
				})
			}
		}

要注意的是,大数据的传输一定是使用post接口的(需要和后端沟通),同时,代码中的fileBuffer名称也是需要和后端沟通的。

转载自:https://juejin.cn/post/7176816492795658299
评论
请登录