重构文件上传行为

发布于:2024-03-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

目标:将 [前端 → 后端] 改成 [前端 → 中间层 → 后端]


第一步:自定义上传行为(ElementPlus)

<template>
    <el-upload
        action=""
        show-file-list
        v-model:file-list="fileList"
        :on-change="handleChange"
        :on-success="handleSuccess"
        :on-error="handleError"
        :http-request="httpRequest"
    >
        <el-button type="primary">Click to upload</el-button>
    </el-upload>
</template>

<script setup>
import { ref } from 'vue';

const fileList = ref([]);

const handleChange = () => {
    fileList.value = fileList.value.slice(-1);
};

const httpRequest = async (item) => {
    const formData = new FormData();
    formData.append('data', item.file);
    formData.append('type', 'cdoShelf');

    const res = await fetch('http://127.0.0.1:8360/upload', {
        method: 'POST',
        body: formData,
    });
    console.log('[res]:', res);
};

const handleSuccess = (...args) => {
    console.log('handleSuccess', args);
};

const handleError = (...args) => {
    console.log('handleError', args);
};
</script>

要点 1:使用 http-request 自定义 el-upload 的上传行为
要点 2:POST 请求的数据格式为 FormData
要点 3:文件以 File 对象的形式传递


第二步:中间层转发(ThinkJS)

const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

module.exports = class extends think.Controller {
    async postAction() {
        const data = this.post(); // 获取 body 参数
        const file = this.file(); // 获取文件
        console.log('[data]:', data);
        console.log('[file]:', file);

        const formData = new FormData();
        formData.append('file', fs.createReadStream(file.data.path));
        formData.append('type', data.type);

        const res = await axios({
            method: 'post',
            url: '后端的上传接口',
            data: formData,
        })
            .then(function (response) {
                think.logger.info('response-data', response.data);
                return response.data;
            })
            .catch(function (error) {
                think.logger.error('error', error);
                return Promise.reject(error);
            });
        console.log('[res]:', res);
    }
};

要点 1:Node 中没有 Fetch API,需要使用第三方库(上例为 Axios)发起请求
要点 2:POST 请求的数据格式为 FormData
要点 3:Node 中没有 File 对象,需要通过 fs 模块创建 Stream 对象来传递文件


本文含有隐藏内容,请 开通VIP 后查看