Vue+Fastapi 上传文件的简单示例

很久没有更新博客了,由于最近在做ResNet 的图像分类和定位相关,但是还没有很大的收获,因此暂缓更新。因为一些原因需要做上传的功能,所以就有了这篇博文了。

目的:网页端文件上传

计划:A:使用Flask 框架 B:使用PHP C:使用Fastapi

计划选用:C

原因:首先就tiny项目而言,越简单越好,如奥卡姆剃须刀原理所讲“如无必要,勿增实体”,也像是某水果公司的“旧”理念——“至繁归于至简”。其次Fastapi 的效率也相对Python的Flask 高一些,不采用PHP是因为这个“世界上最好的语言”局限性太强,虽然有其优点,但是它就像是满嘴繁文缛节的老学究。

步骤分析:创建一个file类型的输入框并隐藏起来,创建两个按钮,一个按钮添加文件,另外一个按钮点击后开始上传。

在我看来,使用Vue 的js比配置Vue环境更简单,因此web端直接使用原生html5即可。代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8″>
    <link rel=”stylesheet” href=”https://unpkg.com/element-ui/lib/theme-chalk/index.css”>
</head>
<body>
    <div id=”app”>
        <el-button @click=”addFile”>addFile</el-button>
        <el-button @click=”uploadFile”>uploadFile</el-button>
        <input type=”file” ref=”upload_input” style=”display: none;” @change=”select_file”>
    </div>
</body>
<script src=”https://unpkg.com/vue/dist/vue.js”></script>
<script src=”https://unpkg.com/element-ui/lib/index.js”></script>
<script src=”https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js”></script>
<script>
    new Vue({
        el: ‘#app’,
        data: function () {
            return {
                select_file_data: ”,
                target_url: ‘http://127.0.0.1:8000/upload’ //上传文件的目标地址,即后台运行的暴露地址
            }
        },
        methods: {
            addFile: function () {
                this.$refs.upload_input.click() //通过ref模拟点击
            },
            uploadFile: function () {
                let uploads = new FormData() //创建FormData
                let config = { headers: { “Content-Type”: “multipart/form-data” } }
                if (this.select_file_data != “”) {
                    uploads.append(“file”,this.select_file_data[0]) //此处只展示上传单个文件
                    axios.post(this.target_url, uploads, config).then(function (res) {
                        console.log(res.data)
                    })
                }
            },
            select_file: function (file) {
                this.select_file_data = file.target.files
                console.log(this.select_file_data)
            }
        }
    })
</script>
</html>
注:其实看了上面代码的小朋友已经发现了我使用了Element-UI ,其实Element官方提供了上传文件的控件,由于代码需要,我并没有直接引用他们的组件。
服务端代码:
# -*-coding:utf-8-*-
from fastapi import FastAPI, UploadFile,File #Fastapi
from fastapi.middleware.cors import CORSMiddleware #跨域调用
import uvicorn
app = FastAPI()
origins = [“*”]# 或者[“http://wicos.me”] 可以自定义允许访问的地址
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=[“*”],
    allow_headers=[“*”],
)
@app.post(“/upload”)
async def recv_file(file: UploadFile = File(…)):
    file_data = await file.read()
    with open(file.filename,”wb”) as fp:
        fp.write(file_data)
    fp.close()
    rt_msg = {
        “name”: file.filename,
        “type”: file.content_type
    }
    return rt_msg
服务端接收文件其实主要是Fastapi 的File 和 UploadFile 两个功能,官方在上传文件方面给了两个实例如下,
我们主要选择使用UploadFile 其二者的区别在于Upload File可以将上传的文件储存在“本地”而不是内存中,对于一些视频,压缩包此类大文件很友好。
其次,Upload File有三个属性和四个async方法:
属性:
  1. filename:文件名
  2. content_type:文件类型
  3. file:返回SpooledTemporaryFile类型文件
四个方法:
  1. read(N):默认读所有的字节,或者read(N) 读入N个字节/字符
  2. write (data):将data写入文件
  3. seek(offset):转到文件中的某个字节位置offset(int)
  4. close():关闭文件

后台再启动服务

uvicorn test:main –reload #test代表后端文件名

以上就是一个简单的上传样例,我已上传到我的GayHub(github)了:https://github.com/Pidbid/vue-fastapi-sample

暂无评论

发送评论 编辑评论


				
上一篇
下一篇