ali-oss没有提供node版本断点续传下载的sdk,于是使用python的sdk写了两个接口:1.断点续传下载 2.获取下载进度。
写在前面:
chrome浏览器的下载管理器就能够实现断点续传下载,但是200G的文件需要十几个小时,时间非常久且网速关系密切。如在业务中大文件下载建议使用百度网盘或其他工具,此处仅作为学习。
代码
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import flask
import json
from flask import request, Flask
import flask_cors
import os
import sys
import oss2
from functools import wraps
progress = 0
'''
flask: seb框架,通过flask提供的装饰器@server.route()将普通函数转换为服务
登录接口,需要传入url,username,passwd
'''
# 创建一个服务,把当前这个python文件当做一个服务
server = flask.Flask(__name__)
flask_cors.CORS(server, supports_credentials=True) # 设置参数
# server.route()可以将普通函数转变为服务 登录接口的路径、请求方式
def allow_cross_domain(fun):
@wraps(fun)
def wrapper_fun(*args, **kwargs):
rst = make_response(fun(*args, **kwargs))
rst.headers['Access-Control-Allow-Origin'] = '*'
rst.headers['Access-Control-Allow-Methods'] = 'PUT,GET,POST,DELETE'
allow_headers = "Referer,Accept,Origin,User-Agent"
rst.headers['Access-Control-Allow-Headers'] = allow_headers
return rst
return wrapper_fun
@allow_cross_domain
def domains():
pass
def percentage(consumed_bytes, total_bytes):
global progress
if total_bytes:
rate = "%.6f" % (float(consumed_bytes) / float(total_bytes))
progress = rate
print('\r{0} '.format(rate), end='')
sys.stdout.flush()
@server.route('/getProgress', methods=['get'])
def getProgress():
resu = {'code': 1, 'data': progress}
return json.dumps(resu, ensure_ascii=False)
@server.route('/ossDownload', methods=['post'])
def ossDownload():
filename = request.values.get('name')
url = request.values.get('url')
path = request.values.get('path')
auth = oss2.Auth('xxxxxxxxxxx', #此处替换为你项目中具体的,下同
'xxxxxxxxxxx')
bucket = oss2.Bucket(
auth, 'http://xxxxxxxxxxx.com', 'xxxxxxxxxxx')
#'bucket','<yourObjectName>', '<yourLocalFile>'
# <yourObjectName>从OSS下载文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
# <yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
# 请将oss2.defaults.connection_pool_size设成大于或等于线程数,并将part_size参数设成大于或等于oss2.defaults.multiget_part_size。
oss2.resumable_download(bucket, url, path + '/' + filename,
store=oss2.ResumableDownloadStore(
root=path),
multiget_threshold=20*1024*1024,
part_size=20*1024*1024,
num_threads=3,
progress_callback=percentage)
resu = {'code': 1, 'message': '下载完成'}
return json.dumps(resu, ensure_ascii=False)
if __name__ == '__main__':
# 指定端口,host,0.0.0.0代表不管几个网卡,任何ip都可访问python
# 测试环境
server.run(debug=True, port=8099, host='0.0.0.0')
# 生产环境
# app = pywsgi.WSGIServer(('0.0.0.0', 8099), server)
# app.serve_forever()
启动
执行python3 server.py
注意警告部分:这里启动服务的时候是debug模式,即测试环境。
调用
1.下载
multiDownload() {
let url = item.url.slice(index + 5); //待下载的文件的地址
let name = item.name.substr(item.name.lastIndexOf("/") + 1); //文件名
let path = this.downloadPath; //要保存在本地的路径,为绝对路径
this.$axios.post("http://xxxxxx:8099//ossDownload?name=" +
name + "&url=" + url + "&path=" + path, {}).then(res => {
if (res.data.code === 1) {
this.success(res.data.message);
}
}).catch(err => {
this.error("下载出错");
});
},
2.获取进度
getProgress() {
this.$axios.get("http://xxxxxx:8099/getProgress")
.then(res => {
}).catch(err => {
});
},