node.js - 尝试通过 axios 发送带有另一个参数的 formData

标签 node.js vue.js axios multipartform-data

我有一个通过 FormData 对象上传单个文件的表单。除了文件属性之外,我还想将此文件分配给一个组。

我不知道如何将组对象 ID 添加到请求中。

这是我的上传组件:

<template>



<div>
      <div class="ui attached segment rounded mb-3">
        <form @submit.prevent="sendFile" enctype="multipart/form-data" class="ui form">
          <div v-if="message" class="`message ${error ? 'text-danger' : 'text-success'}`">
            <div class="message-body"> {{ message }}</div>
          </div>
          <div class="field">

            <label for="file" class="label">Upload File</label>

            <input 
              type="file"
              ref="file"
              @change="selectFile"
              class="file-input"
            />
            <!-- <span class="file-cta">
              <span class="file-icon">
                <i class="fas fa-upload"></i>
              </span>
              <span class="file-label">
                Choose a file...
              </span>
            </span> -->

            <span v-if="file" class="file-name">{{file.name}}</span> 
            <div class="field">
              <button class="btn btn-info">Send</button>
            </div>

          </div>

        </form>
      </div>
    </div>

</template>

<script>
import axios from 'axios'
export default {
  name: "SimpleUpload",

  data() {
    return {
      file: "",
      message: '',
      error: false
    }
  },

  computed: {
    currentGroup() {
      return this.$store.getters.currentGroup;
    }
  },

  methods: {
    selectFile() {
      const file = this.$refs.file.files[0];
      const allowedTypes = ["image/jpeg", "image/png", "image/gif"];
      const MAX_SIZE = 200000;
      const tooLarge = file.size > MAX_SIZE;

      if (allowedTypes.includes(file.type) && !tooLarge) {
        this.file = file;
        this.error = false;
        this.message = '';
      } else {
        this.error = true;
        this.message = tooLarge ? `Too large. Max size is ${MAX_SIZE/1000}kb` : "Only images are allowed"
      }
    },

    async sendFile() {
      const formData = new FormData();
      formData.append('file', this.file);
      formData.append('group', this.currentGroup);
      console.log('file is: ', this.file)
      console.log('this is form data after file is added: ', formData)

      try {
        await axios.post('/uploads', {
          formData,
          group_id: this.currentGroup.id
        });
        console.log('this is the formData being sent: ', formData)
        this.message = 'File has been uploaded';
        this.file = '';
        this.error = false;
      } catch(err) {
        this.message = err.response.data.error;
        this.error = true
      }
    }
  }
}
</script>

这是我的路线:

const Group = require('../models/Group');
const Upload = require('../models/Upload');
const router = express.Router();

const upload = require('../services/file-uploads');

const singleUpload = upload.single('file'); // has to match front end

router.post('/', auth.required, async function(req, res) {
  console.log ('upload route is hit')
  let results = await singleUpload(req, res, async function (err) {
    if (err) {
      return res.status(422).send({ errors: [{title: 'File upload error, detail:  err.message'}] });
    } else {
      console.log('this is the upload reqest fobject: ', req);
      console.log("trying to save data to postgres");
      // console.log('this is the originalname of the reqest file object: ', req.file);
      console.log('this is the upload reqest body: ', req.body.group_id);
      await Upload.query()
        .insert({
          name: req.body.file.originalname,
          users_id: req.user.id,
          filetype: req.body.file.mimetype,
          filesize: req.body.file.size,
          file_url: req.body.file.location,
          groups_id: req.body.group_id
        })
        res.json({
          success: true, 
          message: 'ok'
        });
      res.json(results)
    }
  })
});

module.exports = router;

以及 services/file-uploads 中的上传配置:

const aws = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');

aws.config.update({
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  region: 'us-east-1'
})

const s3 = new aws.S3();

const fileFilter = (req, file, cb) => {
  if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
    cb(null, true)
  } else {
    cb(new Error('Invalid Mime Type, only JPEG and PNG'), false);
  }
}

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: process.env.AWS_BUCKET,
    acl: 'public-read',
    metadata: function (req, file, cb) {
      cb(null, {fieldName: 'TESTING_META_DATA!'});
    },
    key: function (req, file, cb) {
      cb(null, Date.now().toString())
    }
  })
})

module.exports = upload;

在请求中,我看到 body: { formData: {}, group_id: 1 }, 我可以使用 req.body.id 检索 group_id,但 formData 对象为空

最佳答案

像这样准备 FormData:

const formData = new FormData();
formData.append('file', this.file); // Append a file
formData.append('group_id', this.currentGroup.id); // Append a field

然后像这样发送:

await axios({
    method: 'post',
    url: '/uploads',
    data: formData,
    headers: {
        'Content-Type': 'multipart/form-data'
    }
});

关于node.js - 尝试通过 axios 发送带有另一个参数的 formData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60783977/

相关文章:

javascript - 类型错误 : Cannot read property 'path' of undefined in Node js while uploading file

javascript - 在 vuejs 中 chop 已处理的 html

javascript - 如何在 Vue.js 的子组件中正确传递方法?

javascript - 使用回调或 promise 使异步代码像 nodejs 中的同步一样工作

node.js - 蒙戈错误: failed to connect to server in Node-RED

javascript - VueJS : Adding to existing HTML and handling imports

aws-lambda - 无服务器 Lambda 和 API 网关的 CORS 问题

javascript - 错误: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'data' )

node.js - 如何查找 mongoDB 中第 n 层嵌套的对象? (单个集合、单个文档)

javascript - 两个vuejs实例之间通信