文件上传之秒传文件

栏目: IT技术 · 发布时间: 4年前

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

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

为了阅读和开发方便,我将文件上传系列相关文章章节列出来,建议从01节开始看起,文章内容按顺序紧紧相连:

本系列文章相关源码已经上传到github上,请参照下载: https://github.com/lrfbeyond/fast-uploader

为什么会秒传

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

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

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

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

秒传流程

file.uniqueIdentifier

准备

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;
}

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

文件上传之秒传文件

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

文件上传之秒传文件

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

接下来一篇文章,我会介绍如何实现断点续传,跨终端续传文件,敬请关注。


以上所述就是小编给大家介绍的《文件上传之秒传文件》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art and Science of CSS

The Art and Science of CSS

Jonathan Snooks、Steve Smith、Jina Bolton、Cameron Adams、David Johnson / SitePoint / March 9, 2007 / $39.95

Want to take your CSS designs to the next level? will show you how to create dozens of CSS-based Website components. You'll discover how to: # Format calendars, menus and table of contents usin......一起来看看 《The Art and Science of CSS》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具