上篇文章队长讲述了如何把前端上传的文件保存到本地项目目录
本篇 讲述一下把前端上传的文件保存到 第三方存储(七牛云)
七牛云相关步骤思路:
首先 进去七牛云官网,注册并实名认证来获取一个七牛云账号和存储服务器
然后 找到应用于python的存储api
最后 在项目中添加此api以便存储文件时调用
flask项目逻辑思路:
1、根据任务id获取要附加文件的任务
2、获取上传的文件
3、验证文件是否存在
4、调用七牛云存储函数存储文件(存储对象要求二进制)
5、把返回的文件名保存到数据库以便查询下载
附上七牛云接口函数 image_storage.py:
# -*- coding: utf-8 -*- from qiniu import Auth, put_file, etag, urlsafe_base64_encode, put_data import qiniu.config """ 工具类与SDK的区别 工具类: 没有商业利益, 拿来直接使用的. SDK: 开发组件包,保护代码/文档/示例.... 1. 官网, 是有商业价值利益的. 通常由某个公司来维护开发该产品 2. 都需要注册/登录/创建应用(有控制台)/ 3. 获取AK、SK等才能使用. 都需要鉴权后才能使用 4. 详细的接口文档/Demo/技术支持等 """ # 需要填写你的 Access Key 和 Secret Key access_key = '6HpJXhnT1MS70c7GjT--UrvRn6sMsxwDkIQ1fYQq' secret_key = 'rn0V8J7trKklJwTRA8arYoFFCOe6OftoCt_w-s-4' # 我们使用此工具类的目的, 是调用存储图像方法后, 能够获得图像名-->给用户的用户头像路径赋值 def storage(file_data): """上传图片到七牛, file_data是文件的二进制数据""" # 构建鉴权对象 q = Auth(access_key, secret_key) # 要上传的空间 bucket_name = 'itheimaihome' # 我们不需要这个Key. 七牛会自动生成 # 上传到七牛后保存的文件名 # key = 'my-python-logo.png'; # 生成上传 Token,可以指定过期时间等 token = q.upload_token(bucket_name, None, 3600) # 我们这个是通过form表单提交的, 不需要用到put_file方法 # 要上传文件的本地路径 # localfile = './sync/bbb.jpg' # ret, info = put_file(token, None, file_data) ret, info = put_data(token, None, file_data) print 'info: %s' % info print 'ret: %s' % ret if info.status_code == 200: # 表示上传成功, 返回文件名 # 我们上传成功之后, 需要在别的页面显示图像, 因此需要返回图像名 return ret.get("key") else: # 表示上传失败 raise Exception("上传失败") # http://ozcxm6oo6.bkt.clouddn.com/FnTUusE1lgSJoCccE2PtYIt0f7i3
后端flask逻辑代码块
from ihome.libs.image_storage import storage
@login_require def set_user_avatar(): # 图片是以表单提交的 # 一. 获取参数 # 获取用户id user_id = g.user_id # 获取用户头像 image_file = request.files.get('avatar') # 二. 校验参数 if image_file is None: return jsonify(errno=RET.DATAERR, errmsg='图片上传错误') # 三. 逻辑处理 # 1. 调用工具类上传头像 image_data = image_file.read() try: file_name = storage(image_data) except Exception as e: logging.error(e) return jsonify(errno=RET.THIRDERR, errmsg='七牛云存储错误') # 2. 保存文件名到数据库中 try: User.query.filter_by(id=user_id).update({'avatar_url': file_name}) db.session.commit() except Exception as e: db.session.rollback() logging.error(e) return jsonify(errno=RET.THIRDERR, errmsg='mysql存储头像错误') # 四. 返回数据 QINIU_URL_DOMAIN = "http://ozcxm6oo6.bkt.clouddn.com/" # 七牛的访问域名 avatar_url = constants.QINIU_URL_DOMAIN + file_name return jsonify(errno=RET.OK, errmsg='请求成功',data={'avatar_url': avatar_url})
html:
1 <img id="user-avatar" src=""> 2 <div class="menu-text"> 3 <form id="form-avatar" action="/api/profile/avatar" method="post" enctype="multipart/form-data"> 4 选择头像:<input type="file" accept="image/*" name="avatar"> 5 <input type="submit" class="btn btn-success" value="上传"> 6 </form> 7 </div>
js:
1 $(document).ready(function () { 2 // 页面加载好 3 $("#form-avatar").submit(function (event) { 4 // 阻止表单的默认行为 5 event.preventDefault(); 6 // jquery.form.min.js 7 $(this).ajaxSubmit({ 8 url: "/api/v1_0/users/avatar", 9 type: "post", 10 dataType: "json", 11 headers: { 12 "X-CSRFToken": getCookie("csrf_token") 13 }, 14 success: function (resp) { 15 if (resp.errno == 0) { 16 // 上传头像成功, 设置页面中头像展示的url 17 $("#user-avatar").attr("src", resp.data.avatar_url); 18 } else if (resp.errno == 4101 ){ 19 // 表示用户未登录, 跳转到登录页面 20 location.href = "/login.html"; 21 } else { 22 alert(resp.errmsg); 23 } 24 } 25 }); 26 }); 27 })