纯前端上传文件到又拍云-保姆级教程

纯前端上传文件到又拍云-保姆级教程🚀🚀🚀

本文旨在介绍 纯前端上传文件到又拍云、又拍云签名算法、又拍云存储配置相关等 ;帮助开发者快速了解并掌握该上传方法, 点赞+收藏=学会了 🤣

前言

最近在重构 定制头像2.0 开源项目时,接触到了又拍云文件上传;遇到些许迷惑,踩了一些坑;遂以本文记录,望诸位能少踩些许坑~

若只想看代码请下滑至 完整代码 或前往 前端上传文件demo 源代码 ;欲知内部细节,来和采黎一起往下看吧~

相关地址

上传方式

又拍云上传文件的方式有以上三种,我们今天讲的是 前端直传,所以用 FORM API 普通上传,上传文件就以图片举例。

起步

  1. 在又拍云控制台打开 云产品-云存储

image.png

  1. 点击 创建云存储服务 (已有云存储服务可跳过该步骤),这里我创建了一个测试用的云存储——xiaoli-test(bucket名,上传需要)

image.png

  1. 进入功能配置-存储管理页,在最下方找到 操作员授权,新建一个操作员。

image.png

新建后我们便得到一个操作名为 test,密码为 DrKNn10NKKWukeUPur0N1a0D8ET2vEfV (请牢记该密码),并为操作员赋予可写入权限。

image.png

  1. 进入文件管理后,我们创建一个 img 的文件目录,用于存放上传的图片。

image.png

FORM API 上传

请求方法

curl http://v0.api.upyun.com/<bucket> \
    -F authorization="UPYUN <Operator>:<Signature>" \
    -F file=@<filename> \
    -F policy=<policy> \
    # 其他参数...

下文所需字段

  • bucket(云存储服务的名称)xiaoli-test
  • username(操作员名称)test
  • password(操作员密码)0LjHlUNs8n0RWbEPi3c0BB3dOJBkfhwd
  • path(文件上传路径)/img
  • testCdnUrl(测试域名)http://xiaoli-test.test.upcdn.net

测试域名格式:http://bucket.test.upcdn.net.test.upcdn.net 为固定后缀

请求方式【post】

请求域名

官方提供了4个请求地址, 我们这里用 v0.api.upyun.com

  • 智能选路(推荐):v0.api.upyun.com
  • 电信线路:v1.api.upyun.com
  • 联通(网通)线路:v2.api.upyun.com
  • 移动(铁通)线路:v3.api.upyun.com
// 请求地址:https://v0.api.upyun.com/<bucket>
https://v0.api.upyun.com/xiaoli-test

请求参数(必传)

  • file 表单file文件
  • policy policy
  • authorization 授权签名

policy 算法

所需字段如下

  • bucket 云存储服务的名称
  • expiration 过期时间(时间戳秒),这里我们设置10分钟过期。
  • save-key 文件保存的路径(路径包含文件名)
类型格式说明
绝对值String指定具体的路径,如: /path/to/file.txt
时间类{year} {mon} {day} {hour} {min} {sec}日期、时间相关内容(UTC 时间)
md5 类{filemd5}文件的 md5 值
随机类{random} {random32}16 位或 32 位随机字符和数字
文件名{filename} {suffix} {.suffix}上传文件的文件名及扩展名

官方那个提供了5种 save-key,这里我们用最后一种文件名的方式({filename}{.suffix}为帮我们提取到文件名)。

const saveKey' = `${ this.path }/{filename}{.suffix}` /* 得到文件路径 /img/a.png */

计算方法

const policyObj = {  
    bucket: this.bucket,  
    'save-key': `${ this.path }/{filename}{.suffix}`,  
    expiration: new Date().getTime() + 600, /* 过期时间,在当前时间+10分钟 */  
} 
/* 将所需字段转string再转为base64 */
const policy = btoa(JSON.stringify(policyObj))  
uploadData.append('policy', policy);

authorization 算法

所需字段如下

  • policy 上面计算的policy
  • username 操作员名称
  • password 操作员密码

还需引入 https://cdn.xiaoli.vip/tools/upyun/hash.js 文件,里面提供了计算签名所需的 HexMD5b64hamcsha1 hash算法

authorization 组成格式

UPYUN <Operator>:<Signature> 
UPYUN 操作名:<Signature> 
// Signature = Base64 (HMAC-SHA1 (<Password>,<Method>&<URI>&<Policy>)) 
// HMAC-SHA1 返回的原生二进制数据进行 Base64 编码
// Password 密码转md5后
// Method 请求方法 POST
// URI 请求路径 /bucket, /xiaoli-test

计算方法

/* 密码转md */
const passwordMd5 = HexMD5.MD5(this.password).toString(HexMD5.enc.Hex)  
  
/* [Method-请求方法, URI-请求路径, policy] */  
const arr = ['POST', `/${ this.bucket }`, policy]  
  
const authorization = `UPYUN ${ this.username }:${ b64hamcsha1(passwordMd5, arr.join('&')) }`

uploadData.append('authorization', authorization);

返回参数

  • 上传成功:返回 code = 200message = ok 即上传成功。
参数说明
code状态码,200 表示上传成功
messageURL encoding 的描述信息,ok 表示上传成功,其他的表示错误信息
urlURL encoding 的文件保存路径
timeUNIX UTC 时间戳,单位秒
image-width图片的宽。上传文件是图片时,才存在
image-height图片的高。上传文件是图片时,才存在
image-type图片类型。上传文件是图片时,才存在
image-frames图片帧数。上传文件是图片时,才存在
  • 上传失败:返回相应的出错信息,具体请参阅「API 错误码表」。

注意事项

  • 每个请求只能上传一个文件
  • 请求的参数名和参数值 区分大小写,切记区分大小写。

完整代码

html

<input id="upload" type="file" accept=".jpg,.png" @change="uploadImg" />

js(vue)

data() {  
    return {  
        bucket: 'xiaoli-test',  
        username: 'test',  
        password: '0LjHlUNs8n0RWbEPi3c0BB3dOJBkfhwd',  
        path: '/img',  
        testCdnUrl: 'http://xiaoli-test.test.upcdn.net',  
        imgLocalUrl: '',  
        uploadImgList: []  
    };  
},

uploadImg (e) {  
    const file = e.target.files[0]  
    this.imgLocalUrl = URL.createObjectURL(file)  

    /* 创建FormData */  
    const uploadData = new FormData()  
    uploadData.append('file', file);  

    const url = `https://v0.api.upyun.com/${ this.bucket }`  

    /* 计算policy */  
    const policyObj = {  
        bucket: this.bucket,  
        'save-key': `${ this.path }/{filename}{.suffix}`,  
        expiration: new Date().getTime() + 600, /* 过期时间,在当前时间+10分钟 */  
    }  
    const policy = btoa(JSON.stringify(policyObj))  
    uploadData.append('policy', policy);  


    /* 计算 Authorization */  
    const passwordMd5 = HexMD5.MD5(this.password).toString(HexMD5.enc.Hex)  

    /* [Method-请求方法, URI-请求路径, policy] */  
    const arr = ['POST', `/${ this.bucket }`, policy]  

    const authorization = `UPYUN ${ this.username }:${ b64hamcsha1(passwordMd5, arr.join('&')) }`  
    uploadData.append('authorization', authorization);  

    axios({ method: 'POST', url, data: uploadData }).then((res) => {  
        this.uploadImgList.push(this.testCdnUrl + res.data.url)  
    }).catch(e => {  
        console.error('上传失败', e)  
        alert('上传失败')  
    })  

    /* 清除input的值,解决二次上传文件未触发 */  
    document.getElementById('upload').value = ''  
}

所有代码已上传至github, 链接直通车,欢迎start~

鸣谢

使用又拍云应该有近一年了,速度和稳定性都很nice。在很多开源小项目中都有使用,感谢又拍云免费提供云存储、cdn等服务!

余音

本文至此已近尾声,若发现有误处,请大家及时指正,小黎会第一时间更正🙏。欢迎大家一键三连~ 秋风来,蝶花开,再见便是国旗头像了,再会!

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

采黎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值