首页 > 其他分享 >五、文件上传系列-秒传文件

五、文件上传系列-秒传文件

时间:2023-02-18 10:39:46浏览次数:42  
标签:COMMENT 文件 系列 filesize NULL 上传 md5


我们在使用云盘上传文件时会发现秒传文件,速度极快,这是怎么回事呢?秒传文件其实是因为我们要上传的文件前,服务端已经查询到该文件已经存在,没必须再传一份一模一样的文件,直接告诉前端文件已经传好了,让用户有了飞快的感觉。

为什么会秒传

前面说了,因为服务端已经知道文件已经存在服务器端了,也就是说我们要传的这个文件,此前已经至少上传过一次了。这个文件有可能是我们自己上传的,也有可能是别人上传的。

这正是用户需要的,秒传文件,节省上传时间。对后端服务器来说,节约存储空间,同样的文件没必要存成多个文件,同时也节约带宽,当然是好事了。

那服务端是如何知道文件已经上传过了呢?

答案就是MD5。在上一节中我们知道上传前要检测文件md5值。那么本节文章我们将给您介绍如何在文件上传时将md5告诉后端,后端程序如何判断文件已经上传的?

秒传流程

  • 1.前端计算好文件md5,并将md5赋值给文件唯一标识:​​file.uniqueIdentifier​​。
  • 2.前端向后端发送一个get请求,携带md5值,询问后端是否该秒传文件。
  • 3.验证md5,即后端PHP从mysql表中查询是否含有该文件md5值的文件记录,如果有,则返回秒传标识。
  • 4.如果mysql表中没有该文件md5值记录,则按正常上传流程继续上传文件。
  • 5.上传完成后,将该文件md5值记录到数据表中,以便下次验证md5。

准备

1.本文前端基于vue-simple-uploader上传组件,如果您还不了解该组件,请先查看本系列文章01节相关内容。

2.本文后端使用php+mysql,您需要具备相关知识。

3.在mysql数据库中建立hw_file表,表结构如下:

DROP TABLE IF EXISTS `hw_file`;
CREATE TABLE `hw_file` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`filename` varchar(255) NOT NULL COMMENT '文件名',
`filesize` int(11) NOT NULL DEFAULT '0' COMMENT '文件大小',
`md5` varchar(32) NOT NULL COMMENT '文件md5',
`type` varchar(10) NOT NULL COMMENT '文件类型',
`filepath` varchar(128) NOT NULL COMMENT '文件保存路径',
`created_at` datetime NOT NULL COMMENT '上传时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8mb4;

前端发送秒传验证请求

首先,确保开启了服务端分片校验功能,这个功能在vue-simple-uploader的options选项中设置,​​testChunks: true​​, 默认是true开启状态的。

接着选中文件,准备上传前需要计算该文件的md5,关于md5的计算请查看上一节文章。

开启了分片校验功能,目的是每次在正式上传前先向后端发送个get请求,用来实现秒传、续传功能的。



五、文件上传系列-秒传文件_前端

在这个get请求中,在url中会携带文件的md5等相关信息一起传给后端。

在后端验证好文件md5后,会返回相应的是否秒传的标识​​isExist​​,前端要识别这个标识,并及时更新文件上传状态。

在options选项中添加函数​​checkChunkUploadedByResponse()​​,该函数响应后台返回message信息,同时检测分片信息是否上传完整,在后面的断点续传章节会讲到验证分片。

// 服务器分片校验函数
checkChunkUploadedByResponse: (chunk, message) => {
let obj = JSON.parse(message);
if (obj.isExist) {
this.statusTextMap.success = '秒传文件';
return true;
}
},

很显然,当检测到​​obj.isExist​​是true的时候,则表明文件已经存在了,这是直接将文件的上传状态改成:“秒传文件”,并结束上传。

后端验证MD5实现秒传

我们还是继续上一节的后端php文件:Uploader.php。

在获取到前端请求过来的参数中,文件唯一标志​​identifier​​​就是该文件的md5值。然后根据该文件的md5值和该文件的大小filesize,这两个参数,查询hw_file表,得到满足md5和filesize都相当的记录,如果存在记录,则该文件已经上传过了。返回秒传标识:​​isExist = true​​以及文件路径。如果文件不存在,那么就开始上传文件。

//检测断点和md5
public function checkFile()
{
$identifier = $this->fileInfo['identifier'];

//检测文件md5是否已经存在
$rs = $this->checkMd5($identifier, $this->fileInfo['totalSize']);
return $rs;
}

//检测md5表是否已存在该文件
private function checkMd5($md5, $filesize)
{
$db = self::mysql();
$sql = "SELECT count(*) as t,filepath FROM `hw_file` WHERE md5=:md5 AND filesize=:filesize";
$stmt = $db->prepare($sql);
$stmt->execute([
':md5' => $md5,
':filesize' => $filesize
]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$count = $row['t'];
if ($count > 0) {
$res['isExist'] = true;
$res['filepath'] = $row['filepath'];
} else {
$res['isExist'] = false;
}
return $res;
}

运行后,从前端选中文件上传,第一次上传成功:



五、文件上传系列-秒传文件_javascript_02

第二次选择同一个文件上传,或者将文件改名再上传,或者换个浏览器换个终端上传同一个文件,都会是秒传的效果:



五、文件上传系列-秒传文件_前端_03

好了,关于秒传我们就先讲到这里,前后端的具体代码已经上传到github上了,请直接下载运行。

标签:COMMENT,文件,系列,filesize,NULL,上传,md5
From: https://blog.51cto.com/u_15967457/6065083

相关文章

  • 前端Javascript下载文件
    项目开发中经常会有导出数据到Excel类似的需求,或者是下载文档的需求。最简单的下载方式是直接请求服务端文件地址,通过浏览器http实现文件下载。但是开发中,由于项目需求,你要......
  • 大文件读取的实现-PYTHON
    当前一个大文件大小,比当前的机器的内存大,先读取某个文件里的一部分。文件遍历因为文件保存了很多字符和行,因此也是循环常见的典型使用案例,最原始的方法可以调用文件对象的re......
  • PHP超低内存遍历目录文件和读取超大文件
    前言这篇笔记主要解决这么几个问题:PHP如何使用超低内存快速遍历数以万计的目录文件?PHP如何使用超低内存快速读取几百MB甚至是GB级文件?顺便解决哪天我忘了可以通过搜索引擎......
  • 局域网中linux和window共享文件方案——samba
    注明:曾经写过:局域网中如何为Ubuntu20.04和window10共享文件,本文可以视作为该篇的续篇。  ==========================================......
  • DVWA系列 - 额外内容1:同源策略与同站策略的简单理解
    DVWA系列-额外内容1:同源策略与同站策略的简单理解前言在尝试DVWA的CSRF的部分时,偶然学习到了同站策略,感觉与同源策略很相似,因此再来整理下,作为对DVWA系列3:CSRF的......
  • Portswigger 靶场之“文件上传”
    FileuploadvulnerabilitiesAlllabs|WebSecurityAcademy(portswigger.net)1.Remotecodeexecutionviawebshellupload通过Webshell上传远程执行代码......
  • 文件编码转换(GBK转UTF-8)
    publicclassFileReEncoding{Stringfile1="E:\\java-fx";Stringcode1="GBK";Stringfile2="E:\\java-fx-2";Stringcode2="UTF-8";......
  • 原生上传
    <template><divstyle="display:flex;margin:0012px0;flex-wrap:wrap;"><templatev-if="files.length>0"><divclass="imgItem"v-for="(v,i)in......
  • K3S 系列文章-5G IoT 网关设备 POD 访问报错 DNS 'i/o timeout'分析与解决
    开篇《K3s系列文章》《Rancher系列文章》问题概述202206065GIoT网关设备同时安装K3SServer,但是POD却无法访问互联网地址,查看CoreDNS日志提示如下:...[......
  • linux013之文件和目录的权限管理
    用户、组、文件目录的关系:简介:用户和组关联,组合文件目录关联,这样就实现了用户对文件的权限管理。首先来看一下,一个文件或目录的权限是怎么查看的,ls-l,如下,这个信息怎......