使用axios上传文件到阿里云对象文件存储服务器oss

时间:2021-09-14 05:44:01

背景

  • OSS可用于图片、音视频、日志等海量文件的存储。各种终端设备、Web网站程序、移动应用可以直接向OSS写入或读取数据。OSS支持流式写入和文件写入两种方式。使用阿里云oss做文件存储的时候,不可避免的涉及到文件的上传,大概分为两种方式:

服务端验证上传

  • 先将文件传递到应用服务器,再由应用服务器上传至oss服务器,这种方式的优点是简单易懂,nodejs只需要按照文档使用ali-oss中间件上传就行,本文重点不放在这种方式,如果有需要可以私信我。这种方式的缺点是,文件要先上传到应用服务器,再上传到oss,占用带宽资源,过程虽然简单易于操作但是比较繁琐。

服务端签名前端直传

  • 这种方式是我比较推荐使用的,但是需要自己对移动端进行签名,官方的例子给出了一个php版本的签名服务文件,同时上传使用的是plupload这个功能强大,但是不支持模块化使用的插件,于是经过一番琢磨,将php版本的签名服务改成了js版本,同时提供axios版本的文件上传供大家参考,亲测可行。

服务代码:


const crypto =require(‘crypto‘)
async getSingature(ctx){
        ctx.status=200;
        const _config={...}//里面存放阿里云oss的配置参数,不详细说明,用的都应该懂
        const OSSAccessKeyID=_config[‘spring.aliyun.oss.access-key-id‘]
        const OSSAccessKeySecret=_config[‘spring.aliyun.oss.access-key-secret‘]
        const OSSEndPoint=_config[‘spring.aliyun.oss.end-point‘]
        const OSSBucketName=_config[‘spring.aliyun.oss.bucket-name‘];
        let now=new Date();
        const expire=300;
        //签名有效时间五分钟,可自行设定
        const end = now.getTime()/1000   expire;
        //过期时间
        let expiration=new Date((now.getTime()/1000 expire)*1000);
        //oss服务器时间格式iso
        expiration=expiration.toISOString();
        //上传目录
        const dir= ‘‘
        //上传的限制规则
        const condition=[‘content-length-range‘,0,1048576000]
        const start=[‘start-with‘,‘key‘,dir];
        const conditions=[condition]
        const arr={
            expiration,
            conditions
        }
        //上传策略(规则对象转json字符串)
        const policy=JSON.stringify(arr);
        //进行base64编码
        const base64_policy= (new Buffer(policy)).toString(‘base64‘);
        
        const string_to_sign=base64_policy;
        //使用crypto签名
        const signature=crypto.createHmac(‘sha1‘,     OSSAccessKeySecret).update(string_to_sign).digest().toString(‘base64‘);
        const host="http://" OSSBucketName ‘.‘ OSSEndPoint.split(‘//‘)[1];
        const accessid=OSSAccessKeyID;
        //返回结果给前端
        return {
            accessid,
            signature,
            policy:base64_policy,
            expire:end,
            dir,
            host
        }
    }

前端上传:
注意:oss一次只能上传一个文件(只有一个key),可以循环执行post,key为上传到oss后的文件名。signatureObj这里是上面nodejs服务端返回的签名对象

    var file=ducument.getElementById(‘file‘).files[0] 
    var formData = new FormData();
    formData.append(‘key‘,‘上传文件名‘);
    formData.append(‘name‘,file.name)
    formData.append(‘policy‘,signatureObj.policy)
    formData.append(‘OSSAccessKeyId‘,signatureObj.accessid)
    formData.append(‘success_action_status‘,‘200‘)
    formData.append(‘callback‘,‘‘)
    formData.append(‘signature‘,signatureObj.signature)
    formData.append(‘file‘,file.file)
    axios({
    url:url,
    method:‘post‘,
    data:formdata,
    headers: { ‘Content-Type‘: ‘multipart/form-data‘ }
})