关于elementt的upload图片上传标签的解读,上传视频。上传大文件切片——生成一个哈希值,Message的消息提示。

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于elementt的upload图片上传标签的解读,上传视频。上传大文件切片——生成一个哈希值,Message的消息提示。相关的知识,希望对你有一定的参考价值。

<el-upload 
    action="https://jsonplaceholder.typicode.com/posts/"
    提交图片的服务器地址
    :on-preview="handlePreview" 
    :on-remove="handleRemove" 
    :before-remove="beforeRemove" 
    以上是三个事件
	 multiple
	 这个意思是上传多张
    :limit="3" 
    限制最多上传几张
    :on-exceed="handleExceed" 
    :file-list="fileList"
    两个事件
    >
    
    <el-button size="small" type="primary">点击上传</el-button>
    <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>

这里暂且用的到的有:

头像图片上传

这样写就是一次传一个。

<el-upload action="" :on-change="changeHandle">
	<el-button size="small" type="primary">点击上传头像</el-button>
	<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>

属性说明类型
on-change文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用function(file, fileList)

这个函数里的参数一就是我上传的一个头像文件file对象

changeHandle(response) 
    console.log(response);


可以看出对象的类型Wie:File。那么如何将file上传到服务器呢,
把File对象传到服务器

得到对象:里面的row对象。
changeHandle(response) 
	console.log(response);
	const formData = new FormData()
	formData.append('file', response.raw)
,

++++++++++++++++分割线解读++++++++++++++++++

const formData = new FormData();
给forData这种Map类型添加一个属性file::file.row。
formData.append('file', response.raw);

然后直接将表单对象传输上去:

let ret = await uploadAvatar(formData);
uploadAvatar:封装好的ajax,服务器去解析。

上传视频

nodejs搭建服务器,然后设置一个公共资源路径,请求数据返回一个路径

// 设置静态资源目录
app.use(express.static('./public'))//目录下面有视频
app.post("/msg",(req,res)=>
    console.log("我post被访问了");
    res.send(
        code:Date.now(),
        data:"http://localhost:4000/niu.mp4"
    )
)

客户端
el-upload标签自带一个axaj。

<el-upload action="http://localhost:4000/msg" 
	:on-success="uploadSuccess"
	:show-file-list="false">
		<el-button size="small" type="primary">点击上传视频</el-button>
</el-upload>


:on-success事件:上传成功后返回其响应内容;

uploadSuccess(response)//参数就是一个响应体。
    console.log(response);

当选择一个视频上传完可以在控制台查看其返回响应,状态如何。

但是这种写法有好有坏。方便维护,不利于安全。

大文件上传——方案

那么遇到超大文件,或者比较大的文件的时候该怎么传:

<el-upload>有个on-change属性,上面就是说过,第一个参数就是传输的文件本身。

  • 对于文件较大的文件上传进行分片上传,把一个大文件,拆分成若干个小的文件,然后再上传。
  • 切成小的方案
      1. 指定大小,然后来切文件 大小固定,数量不定
      1. 指定数量,然后来切文件,数据固定,大小不定
  • 上传时,要有一个编号,这样在服务器端才能根据此编号完成文件的合并操作
  • 还需要根据文件的内容,生成一个根据内容来得到的一个唯一随机字符串,此字符串一定要和内容是关联,只要内容有变化,则随机字符串要有变化,如果内容没有变化,则字符串不变(hash字符串[hash值])
  • 如果你没有此hash值,这样有可能在上传过来中,如果有两个相同的文件,就会上传两次,不太好
  • 有hash值,在合并的时候,可以用此hash值,来当作合并后的文件名称

hash值_0.mp4
hash值_1.mp4
hash值_2.mp4
==> hash值.mp4 完整的文件

<el-upload action="http://localhost:4000/msg" 
:on-success="uploadSuccess"
:show-file-list="false"
:on-change="changeHandle">
	<el-button size="small" type="primary">点击上传视频</el-button>
</el-upload>

*******
methods:

得到切片的大小:
当前的索引值是多少:

changeHandle(file)
    if(!file) return
    console.log(file.raw.size);
    let partnum = 4;//切片数
    console.log(file.raw.size/partnum);//每一块的大小
    let currentIndex = 0;//当前的索引值是多少

生成一个哈希值

在线MD5生成https://www.sojson.com/md5/

安装一个插件包,给定内容生成一个哈希值(加密稳定)

安装
npm i -S spark-md5
导入
import SparkMd5 from "spark=md5" 
给定一个内容生成一个md5.

要把内容转成哈希值之前,先要把内容转为arrayBuffer对象。buffer二进制数据流。把得到的buffer数据流转为一个hash值。

const read = new FileReader();/* 一个类的实例对象 */
read.readAsArrayBuffer(file.raw);/* 将file.raw转为arraybuffer */
read.onload = evt=>console.log(evt.target.result);

封装成一个函数:(异步)

async changeHandle(file)
            if(!file) return
            console.log(file.raw.size);
            let partnum = 4;//切片数
            console.log(file.raw.size/partnum);//每一块的大小
            let currentIndex = 0;//当前的索引值是多少
            let result = await this.binary(file.raw,"arraybuffer");//生成arraybuffer数据流
            console.log(result);
        ,
binary(fileobj,type='binary')
    return new Promise((resolve,reject)=>
        const read = new FileReader();
        if(type == 'binary')
            read.readAsBinaryString(fileobj);//普通二进制数据流(照片啥的)
        else
            read.readAsArrayBuffer(fileobj);//arraybuffer类数据流(大文件,视频啥的)
        
        read.onload = evt=>resolve(evt.target.result);//返回最终的生成结果
    )
,


把得到的buffer数据流计算出来一个hash值

根据文件内容得到一个hash字符串,当做切片的前缀。得到文件扩展名。

let spark = new SparkMd5.ArrayBuffer();
spark.append(result)//把buffer的结果以流的形式填充进去的
let hash = spark.end();//结束的话返回一个字符串
console.log("hash:",hash);
// 得到一个文件的拓展名
let extName = file.raw.name.split(".").pop();
console.log(extName);

切片存储:

// 存储切好的文件,数组
let partList = [];
for(let i=0;i<partnum;i++)
    let chunk = file.raw.slice(currentIndex,partSize);//文件切片
    partList.push(
        filename:`$hash_$i.$extName`,
        chunk:chunk
    )
    currentIndex += partSize;

console.log(partList);

this.partList = partList;
this.hash = hash;

将生成的多个小文件,串行按序请求网络。

let requertList = [];//存储每一个异步请求方法
partList.forEach((filename,chunk)=>
    const requestFn = ()=>
        return new Promise((resolve,reject)=>
            setTimeout(() => 
                resolve(filename)
            , 1000);
        )
    ;
    requertList.push(requestFn);
)
/*串行执行方法,每一个每一个的执行*/
let index = 0;
const next =async ()=>
    if(index>=requertList.length)
        console.log("传输完成");
        return;
    
    let name = await requertList[index++]();
    console.log(name);
    next();

next();

通过表单对象,上传切片的文件。

partList.forEach((filename,chunk)=>
	const requestFn =async ()=>
	const formData = new FormData();
		formData.append("filename",filename);
		formData.append("chunk",chunk);
		let msg = await post("http://10.9.46.247:4000/msg",formData);
		console.log("msg:",msg);
	;

	requertList.push(requestFn);
)


Message的消息提示

this.$message("上传失败");
this.$message.error("上传失败");
this.$message.success("上传成功");
<template>
    <el-container>
        <el-header>Header</el-header>
        <el-container>
            <el-aside width="200px">
                <Enmu />
            </el-aside>
            <el-container>
                <el-main>
                    <el-breadcrumb separator="/">
                        <el-breadcrumb-item :to=" path: '/' ">首页</el-breadcrumb-item>
                        <el-breadcrumb-item><a href="/">活动管理</a></el-breadcrumb-item>
                        <el-breadcrumb-item>活动列表</el-breadcrumb-item>
                        <el-breadcrumb-item>活动详情</el-breadcrumb-item>
                    </el-breadcrumb>
                    <el-input placeholder="请输入内容" clearable class="shuru">
                    </el-input>
                    <el-button type="primary">点击搜索</el-button>
                    <el-button type="success">添加信息</el-button>
                    <el-button type="danger">删除选中</el-button>
                    <el-divider></el-divider>


                    <el-form ref="form" :model="form" label-width="80px">
                        <el-form-item label="账号" prop="input">
                            <el-input v-model="form.input"  />
                        </el-form-item>

                        <el-form-item label="上传头像">
                            <el-upload action="" :on-change="changeHandle">
                                <el-button size="small" type="primary">点击上传头像</el-button>
                                <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
                            </el-upload>
                        </el-form-item>
                        <el-form-item label="上传视频">
                            <el-upload action="http://localhost:4000/msg" 
                            :on-success="uploadSuccess"
                            :show-file-list="false"
                            :on-change="changeHandle">
                                <el-button size="small" type="primary">点击上传视频</el-button>
                            </el-upload>
                            <el-divider></el-divider>
                            <video v-if="src" :src="src"  width="200px" height="300px"  controls poster="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fp3.itc.cn%2Fq_70%2Fimages01%2F20210619%2Fa7afb11dcd09419a911da798e6aa8878.png&refer=http%3A%2F%2Fp3.itc.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666056532&t=3b092bbb7b19927dd0b2e1ee4e93463d"></video>
                        </el-form-item>
                        <el-button type="success" @click="submitForm('form')">点击上传</el-button>
                    </el-form>

                    <!-- <el-image style="width: 100px; height: 100px" :src="form.avatar"  fit="fill"></el-image> -->
                </el-main>
                <el-footer>Footer</el-footer>
            </el-container>
        </el-container>
    </el-container>

</template>

<script>
import Bn from "@/components/Btcm.vue"
import Enmu from "@/views/menu"
import SparkMd5 from 'spa

以上是关于关于elementt的upload图片上传标签的解读,上传视频。上传大文件切片——生成一个哈希值,Message的消息提示。的主要内容,如果未能解决你的问题,请参考以下文章

关于文件上传-图片上传

iview关于Upload 上传遇到的问题

jQuery File Upload文件上传插件简单使用

vue + elementui upload上传图片到服务器以及保存后回显问题

vue+el-upload 上传图片和视频小总结

layui实现文件或图片上传记录