前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >0元免服务器,开发个人专属网盘 | 云开发WEB最佳实践

0元免服务器,开发个人专属网盘 | 云开发WEB最佳实践

原创
作者头像
腾讯云开发TCB
修改2020-03-31 15:32:59
2.3K0
修改2020-03-31 15:32:59
举报
文章被收录于专栏:云开发云开发云开发

导语

有的时候我们传输文件的场景是特别难受的。

比如去打印店要打印文件,一般来讲是我们登录社交软件,然后传输文件,最后退出登录;除了安全性极差,还特别繁琐。

即使是在我们自己的设备上,使用社交软件传输文件还会面临着存储大小的限制,我们不得不又依赖存储介质才能完成传输。

为何不做一个工具,来解决这个让人难受的问题呢?

我希望有个工具只要有互联网就可以用,而且没有文件传输的限制。最重要的是传输效率不能小于社交软件。

对于程序员来讲,只要心中有想法,没有什么是不能实现的,阻碍程序员去实现的最大障碍是技术方法。

这个想法我很早就有了,不过按照自己的需求,我需要服务器,我需要很强的带宽,而这些足以让我止步不前了。

当 WEB 云开发推出的时候,我的眼前一亮。在细细品味之后,觉得粮草到位了,可以开战了。

实践

按照自己的想法,在解决了一点小问题之后,我的跨平台文件转储工具就完成了。为此我将其命名为 FILES。

这是 FILES 的最终形态,包含两大最核心也最基础的功能,存文件和取文件。

存文件时可以选择添加存储密码,也可以勾选取后即删。存储密码是为了防止他人窃取,增加存储的安全性。

每个文件存储时长为 6 小时,你可以在 6 小时之内任意取文件,不限次数,特别适用于给多人发大文件。

当勾选取后即删时,文件将会在第一次取完即删除,不会再次被取。

上传成功的文件将显示如下形态,像当于取件凭证;你可以复制凭证给要发送的人。

你可以随时查看自己的存储文件,这会有文件的基本信息以及剩余存储的时长。

在取文件时,需要取件号码和存储密码。如果存文件时没有设置密码,则存储密码可以为空。

点击下载文件时,会弹出腾讯验证码,用来防止恶意刷接口的出现。

工具需要用一用才知道,我们来一波实际的测试。首先整一个 400M 的文件,进行上传测试:

使用工具进行上传,在作者自己的网络条件下,发送带宽在 5-8Mbps,峰值可达 14Mbps。

为了证明是作者自己的 10M 网速拖累了工具的传输速度,特晒出网络测试的上传速度

(此测速节点是上海电信)
(此测速节点是上海电信)

我们来看一下下载速度,同样受制于作者的网络,下载文件的速度基本上保持在 2M/S 的水平。

我们来对比一下常用传输文件的 QQ 速度,在同一个电脑中进行上传传输文件,速度如下:

这一对比就觉得工具是如此的香,而且工具是没有文件大小限制的,想传多大就传多大。由于作者使用的是按量付费的云开发,所以更加划算。使用了半个月以来,传输的文件也很多,费用还没超过 5 元钱。

作者公开使用网址:https://f.dnuise.cn

技术细节

前端页面逻辑的实现上,使用原生 JS 搭配 WEB 云开发 SDK 包,与云开发后端服务进行交互。

初始登录

在使用之前,需要进行客户端的认证,否则云开发无法做文件和数据库的权限调配。在之前的云开发上有微信认证,但使用门槛过高,不适合游客类的 web 开发。

在目前的 web 云开发能力上,我们推出匿名登录和自定义登录,完美的适用绝大部分的开发需求。

FILES 使用了匿名登录做初始化,代码细节如下:

/**
 * 启动服务
 */
window.onload=function(){
    try{
        initTcb();
    }
    catch(e){
        showModel('此浏览器不支持文件服务,请到其他浏览器打开!', 40000, 'error');
    }
};

/**
 * 云开发SDK初始化服务(匿名登录)
 * @param success 成功的callback
 */
function initTcb(success=()=>{}) {
    app = tcb.init({
        env: 'cloud-8b9880'
    });
    const auth = app.auth();
    //匿名登录方法
    auth.signInAnonymously().then(() => {
        auth.getLoginState().then((e) => {
            uid = e.credential.refreshToken;
            console.log('匿名登录成功,初始化完成!');
            initFlag = true;
            success();
        });
    }).catch(err => {
        showModel('初始化失败,请检查网络后重新刷新页面!如果一直出现此情况请反馈给腾讯云云开发', 10000, 'error');
    });
}

页面加载时执行匿名登录方法,登录成功后,就可以使用 web-sdk 包来做更多与云开发后端服务交互的事情了。

上传文件

我们在 web 页面中选择文件,设定了密码和删除逻辑后,就需要调用云开发的文件上传 API 来将文件上传。

function uploadFile() {
    //之前的逻辑标志,判断是否登录
    if (initFlag) {
        let fileName = fileSaver.files[0].name;
        let nowTime = new Date().getTime();
        //文件上传API
        app.uploadFile({
            cloudPath: uid+'/'+nowTime+'/'+fileName,
            filePath: fileSaver.files[0],
            //上传监听
            onUploadProgress: function (progressEvent) {
                let percentCompleted = Math.round(
                    (progressEvent.loaded * 100) / progressEvent.total
                );
            }
        },function (err,res) {
            if(err){
                console.log('上传文件失败,请重新尝试上传![权限或网络异常]');
            }
            else{
                app.callFunction({
                    name:'upload',
                    data:{
                        file:res.fileID,
                        key:getElm('userKey').value,
                        name:fileName,
                        one:getElm('oneTime').checked,
                        uid:uid
                    }
                }).then(res => {
                    console.log(res);
                    if(res.result.code===0){
                        showModel('上传文件成功!', 3000, 'success');
                    }
                    else{
                        showModel('文件确认失败,请检查网络重新上传!如果这不是第一次,可能使用人太多,请稍后再试', 6000, 'error');              
                    }
                }).catch(err =>{
                    showModel('文件确认失败,请检查网络重新尝试上传![权限或网络异常]', 6000, 'error');
                });
            }
        });
    } else {
        showModel('当前未初始化,请重新刷新页面!如果一直出现此情况请反馈给腾讯云云开发', 10000, 'error');
    }
}

上传完毕后,会调用云函数 upload,将文件的存储路径和设置的信息保存到数据库中。

文件下载

下载文件时,由于使用了腾讯云验证码,需要获取用户的 IP 地址。这样一来原本的云函数调用就失去了作用。

云函数推出了一个非常有用的能力,HTTP 触发。

使用 http 触发,在客户端可以像正常的 http 请求一样调用云函数,而调用的请求头也会被云函数得到。

FILES 使用 HTTP 请求访问云函数实现下载功能的代码如下:

WEB 页面

function downloadFile(res) {
    //获取腾讯验证码状态
    if(res.ret!==0)return;
    //判断微信客户端
    if(isWeClient()){
        showModel('此浏览器不支持下载文件,请用其他浏览器!',10000,'error');
        return;
    }
    let no = getElm('downNo').value;//取件号
    let key = getElm('downKey').value;//取件密码
    //作者自己封装的HTTP请求方法(JSON)
    calls({
        url:'https://tcb-url/getFile',
        data:{
            uid:uid,
            no:no,
            key:key,
            code:res
        },
        success(res){
            if(res.result.result.code===0){
                showModel('文件请求成功,正在拉起下载!', 3000, 'success');
                //作者封装的文件下载方法
                downLoad(res.result.result.url,res.result.result.name);
            }
            else if(res.result.result.code===1){
                showModel('取件号码不存在,或者密码错误!', 6000, 'warning');            
            }
            else{
                showModel('系统繁忙,可能使用人数太多,请稍后再试!', 6000, 'error');               
            }
        },
        fail(){
            showModel('系统繁忙,维护中,请稍后再试!', 6000, 'error');         
        }
    });
}

云函数端:

const tcb = require("tcb-admin-node");
const request = require('request')
tcb.init({
    env:"env-id"
});
let CallWeb = (obj) =>{
    //请求腾讯验证码真伪
    return new Promise((resolve, reject) => {
        request({
            url:'https://ssl.captcha.qq.com/ticket/verify'+
                '&Ticket='+obj.ticket+
                '&Randstr=' + obj.randstr +
                '&UserIP =' + obj.ip,
            method:'GET'
        }, (error, response, body) => {
            if (error) {
                reject(error);
            }
            resolve((typeof response.body === 'object') ? response.body : JSON.parse(response.body));
        });
    });
}

exports.main = async event => {
    let AllowOrigin='https://tcb.cn'
    //设置同源策略,只接收此源下的请求
    if(event.headers.origin==="https://tcb.cn"||event.headers.origin==="http://tcb.cn"){
        AllowOrigin = event.headers.origin;
    }
    console.log(event.body);
    let result = {};
    const ip = event.headers["x-real-ip"];
    if(event.body!=null && event.body[0]==='{' && JSON.parse(event.body).code!=null){
        const data = JSON.parse(event.body);
        result = await CallWeb({
            ticket:data.code.ticket,
            randstr:data.code.randstr,
            ip:ip
        });
        //如果腾讯验证码为真则调用downFILE获取文件地址
        if(result.err_msg==="OK"){
            result = await tcb.callFunction({
                name: "downFile",
                data: data
            });
        }
        else{
            result.code=300;
        }
    }
    else{
        result.code=404;
    }

    return {
        statusCode: 200,
        headers: {
            'content-type': 'application/json',
            'Access-Control-Allow-Origin': AllowOrigin,
            'Access-Control-Allow-Methods':"POST,OPTIONS",
            'Access-Control-Max-Age':'3600',
            'Access-Control-Allow-Headers':'Content-Type'
        },
        body: {
            result
        }
    };
}

未来规划

FILES 将是跨平台的存储工具,也就是说需要同时支持微信小程序,qq 小程序,这样就可以方便的选择微信文件和 QQ 文件了。

而跨平台特性,正式云开发所擅长的,所以在不久的几个月后,小程序版本的 FILES 存储就会出现。

这样一来才算真正的跨平台无缝传输。为了一起学习和交流,改进产品特性和效率,作者特将项目开源,欢迎有兴趣的开发者们来尝试体验。

详细的部署和操作步骤都在项目 RAEDME 中展示。

项目地址:关注公众号「腾讯云云开发」回复关键词 " 存储 " 即可获取 。

云开发(CloudBase)是一款云端一体化的产品方案 ,采用 serverless 架构,免环境搭建等运维事务 ,支持一云多端,助力快速构建小程序、Web应用、移动应用。

技术文档:https://www.cloudbase.net/

微信搜索:腾讯云云开发,获取项目最新进展

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导语
  • 实践
  • 技术细节
    • 初始登录:
      • 上传文件:
        • 文件下载:
        • 未来规划
        相关产品与服务
        云开发 CloudBase
        云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档