1、使用模板来进行文件上传
1.1 创建一个模板及视图函数
模板代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
#当表单里面需要上传文件的时候 必须设置这个参数 enctype="multipart/form-data"
<form action="/file" method="post" enctype="multipart/form-data">
头像:<input type="file" name="file"><br>
<input type="submit">
</form>
</body>
</html>
视图函数
@app.route('/')
def hello_world():
return render_template('demo.html')
我们可以使用 python app.py 来启动Flask
访问 http://127.0.0.1:5000/
1.2 选择文件点击提交,视图函数接收文件并保存
在点击提交按钮的时候,我们也需要访问一个视图函数
@app.route('/file',methods=('POST',))
def file():
#首先接收文件,使用的是files方法
f = request.files.get('file')
#以二进制格式打开一个文件,文件名可以随便指定
with open('1.jpg','wb') as file_data:
#首先用read()的方法,将图片读取成二进制的形式,然后写入的文件当中
file_data.write(f.read())
#保存完图片之后 返回一个字符串 保存成功
return '保存成功'
2、使用Ajax前后分离的方式来上传文件
2.1 首先我们在静态文件夹(static)中创建一个html文件,这样我们可以直接访问
#在这里 我导入了两个js文件 一个是jQuery库 一个是jQuery库里面的一个表单插件,我们可以通过这个插件来进行文件上传
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/js/jquery.form.min.js"></script>
<script src="/static/js/jquery.min.js"></script>
</head>
<body>
<form action="">
头像<input type="file"><br>
<input type="submit">
</form>
</body>
</html>
2.2 通过js事件来上传文件
<script>
$(function () {
$('#av').submit(function (e) {
//阻止表单默认时间
e.preventDefault()
$(this).ajaxSubmit({
url: '/ajaxfile',
type: 'post',
success: function (data) {
console.log(data)
}
}
)
})
})
</script>
2.3 后台视图函数进行接收,接收的时候,基本和前面模板相同,唯一不同的是返回值,因为此次是ajax上传的,所以我们需要返回json数据
@app.route('/ajaxfile',methods=('POST',))
def ajaxfile():
f = request.files.get('file')
with open('2.jpg', 'wb') as file_data:
file_data.write(f.read())
return jsonify(msg='保存成功')
3、文件的保存
前面不管是通过什么方式文件上传,但是我们都是保存在本地,保存到本地的话,也会出现很多问题,比如:
- 保存到本地,扩容,磁盘满的问题
- 备份不方便
- 多机存储不方便
- 同一张图片 保存两次 浪费空间
用户 | 图片 |
---|---|
用户A | 图片1 |
用户B | 图片1 |
这样的话两个用户都是上传的同一张图片,但是服务端却把两张图片都保存了,造成空间浪费
- 同名图片 但是不是同一张
比如两个用户A、B,分别上传了一张照片,但是这两张照片名字一样,但是内容不一样,这样如果不当处理,可能后面上传的图片会把前面的图片给覆盖
对于上述问题给出了以下文件存储解决方案
- 自己搭建文件存储系统,比如有:
FastDFS 快速分布式文件存储系统
HDFS hadoop分布式文件系统 - 选择第三方服务-----七牛云存储
4、七牛云的使用
今天我也主要介绍的就是七牛云的使用,我们可以把文件保存到七牛云提供的空间里,而它给我们提供一个链接地址,这样我们就可以通过这个链接地址来访问文件了。
七牛云在提供服务的时候,不是通过空间大小进行收费,而是通过访问流量大小来进行收费。
用七牛云的话,我们就可以轻松解决上述的问题,那么它是怎么解决的呢?
它对于图片,不是一文件名、文件大小来识别的,而是通过类似MD5这些算法来存储,MD5是一种单向加密,这种算法也可以对文件来进行加密,因为文件在计算机当中也是二进制存储的,所以七牛云会先把文件进行哈希,然后把这个哈希值,有没有在我空间里面有存储,如果有的话,就直接存一个名字就可以了,没有的话,就存储这个文件,这样的话,就可以轻松解决上述的问题。
4.1 注册并生成一个存储空间
-
注册完成之后点击添加对象存储
-
新建一个存储空间,用来存储文件的,存储区域选择华东比较好
-
创建好了之后,你就会看见你的存储空间,然后接下来就可以使用了
-
先点击右上角的文档—> 开发者中间 (这里有一些帮助文档,官方也把各种接口给我们做好了) -----> 菜单栏的’SDk&工具’ ----> 官方SDK
-
这里我们主要用的是python 所以选择python语言
-
首先我们需要安装qiniu 这个包(
pip install qiniu
或
easy_install qiniu)这两个命令都可以,官方也提供了源码安装,你可以自己去看看
@app.route('/ajaxfile', methods=('POST',))
def ajaxfile():
# 从前端获取文件
f = request.files.get('file')
# 首先导入七牛云的包
from qiniu import Auth, put_data
# 需要填写你的 Access Key 和 Secret Key
access_key = 'Access_Key'
secret_key = 'Secret Key'
# 构建鉴权对象
q = Auth(access_key, secret_key)
# 要上传的空间
bucket_name = 'python07'
# 上传后保存的文件名
# key = 'my-python-logo.png'
# 生成上传 Token,可以指定过期时间等
token = q.upload_token(bucket_name, None, 3600)
# 要上传文件的本地路径
# localfile = './sync/bbb.jpg'
# ret保存的是文件哈希值 和 文件名 由于我们这里没有指定文件,所以文件名和哈希值一样
# info 是一些存储信息
ret, info = put_data(token, None, f.read())
return jsonify(msg='保存成功')
代码中的Access Key 和 Secret Key需要填写你自己的,在七牛云点击头像有一个密钥管理,然后替换成你自己的就可以了
- 当我们上传成功后,七牛云会提供一个地址,我们可以通过地址去查看图片,在存储空间的空间概览当中,有一个【CDN 测试域名】,然后用这个域名去拼接文件名就可以了
这样就可以了,当然这个连接我们可以传给前端,然后再显示出来,头像的上传和显示就可以这么做了