七牛是不错的云存储产品,特别是有免费的配额可供使用,存点小文件或者博客的插图什么的还是不错的。以下介绍在自己的 Web 应用中上传文件到七牛的方法。
基本思想
当我们想把本地的文件通过浏览器上传到自己的七牛云存储空间上时,就有两种思路
- 将文件直接上传到服务端,再由服务端将文件传输至七牛
- 向服务端请求七牛的文件上传token,然后将文件上传至七牛(授权式上传)
第1种方法较好解决,参考七牛的文档即可,第2种方法效率较高,这里介绍第2种。使用Javascript在Web前端上传文件的方法,七牛官方给出了文档和例子。核心内容在于这几点:
- 指定上传按钮的ID
- 创建一个uploader
2.1 绑定上传按钮的ID
2.2 设置获取上传token的服务端url
1 | <div id="btn-uploader"> |
这里上传按钮的ID是pickfiles
1 | uploader = Qiniu.uploader({ |
设置uploader的参数
七牛的Javascript SDK使用到了Plupload,在初始化uploader
时,可以为其传递Plupload中给定的Option,而不仅局限于七牛例子中给出的。例如可以添加multi_selection
和filters
来限制上传时,文件的选择。
文件命名
当文件上传至七牛云存储时,文件的命名显得尤为重要,缺省情况下,七牛会使用上传文件的名字命名,然而文件重名将难以避免,并且重名将导致无法上传或覆盖旧文件。为了解决这一问题,有三种方法
- 由qiniu自动生成唯一的文件名,在
uploader
中设置unique_names=true
- 由服务端生成文件名,在
uploader
中设置save_key=true
,并且在服务端返回token时,设置policy.saveKey
的值为所要保存的文件名。- Web 前端自定义文件名,
key
函数中设置文件名,缺点是文件名无法有效管理。
以下使用Python和Flask框架为例,介绍服务端生成文件名的方法。
1 | import json |
服务端会返回如下格式的JSON,里面已包含了文件名
1 | { |
但是服务端仍无法获悉本地文件的文件类型,因此无法给出恰当的文件名,虽然设置文件名时缺失扩展名,不影响文件的下载,但明显不漂亮。
这时就需要先在本地先获取文件扩展名后,再向服务端请求,由服务端安排一个文件名(服务端掌握所有文件的信息,可以方便文件的命名和管理)。
在uploader
的init
参数中,有一个key
参数,可以为其绑定函数来设置文件名。该函数启用的前提是save_key
和unique_names
设为false
。
在key
对应的函数中使用ajax向服务端请求文件名,然后与文件的扩展名组合后就得到了恰当的文件名了。特别注意的是,这里的ajax调用用使用同步的方式,因为需要在该函数返回前就得到服务端回应的信息,如果使用异步的方式,函数都返回了,服务端还没响应呢。
1 | uploader = Qiniu.uploader({ |
以下是uploader的详细设置,其他完整的信息请参考七牛的例子,并加以改造。
1 | uploader = Qiniu.uploader({ |