首页 > 解决方案 > 如何在 Vuejs 和 Expressjs 中上传文件

问题描述

嘿,请是 Vuejs 和 Express 的新手……所以我正在尝试练习。

因此,我尝试使用 Vuejs 和 ExpressJs 创建一个带有图像的用户配置文件,但没有上传任何文件或文本。

这是我的CreateProfile.vue文件

       <div class="icon-pic">
       <label for="Password">Upload your Logo / Picture</label>
        <input type="file" ref="file" @change="handleFileUpload"/>
      </div>

      <b-input-group class="mb-2">
        <b-form-input
          id="input-small"
          type="text"
          placeholder="Enter your Name"
          required
          :rules="[rules.required]"
          v-model="profile.fullname"
        ></b-form-input>

        <b-form-input
          id="input-small"
          type="text"
          placeholder="Enter your BrandName"
          v-model="profile.brandname"
        ></b-form-input>
      </b-input-group>

注意:还有其他输入...

下面是我的表单脚本函数

<script>
import ProfileService from '@/services/ProfileService'

export default {
data () {
return {
  profile: {
    fullname: null,
    brandname: null,
    skill1: null,
    skill2: null,
    skill3: null,
    skill4: null,
    socail_handle1: null,
    socail_handle2: null
  },
  file: null,
  error: null,
  rules: {
    required: (value) => !!value || 'Required.'
  }
}},
methods: {
handleFileUpload () {
  const file = this.$refs.file.files[0]
  this.file = file
},
async create () {
  this.error = null
  const formData = new FormData()
  formData.append('file', this.files)
  const areAllFieldsFilledIn = Object.keys(this.profile).every(
    (key) => !!this.profile[key]
  )
  if (!areAllFieldsFilledIn) {
    this.error = 'Please fill in all the required fields.'
    return
  }
  try {
    await ProfileService.post(this.profile, formData)
    this.$router.push({
      name: 'profile'
    })
  } catch (error) {
    this.error = error.response.data.error
  }
}}}

下面是我的ProfileController.js文件

const {Profile} = require ('../models')
const multer = require ('multer')

const fileFilter = (req, file, cb) => {
const allowedTypes = ["image/jpeg", "image/jpg", "image/png"]
if (!allowedTypes.includes(file.mimetype)){
const err = new Error('Incorrect File');
return cb(err, false)
}
cb(null, true)
}

const upload = multer ({
dest: '../public',
fileFilter,
})

module.exports = {
async post (req, res){
    try {
        upload.single('files')
        const profile = await new Profile({
        profile: this.profile,
        files: req.file
      });
      profile.save().then(result => {
        console.log(result);
        res.status(201).json({
          message: "Done upload!"
        })
      })
    } catch (err) {
        console.log(err)
        res.status(500).send({
        error: 'An Error has occured trying to fetch'
    })}}

跟随我的Model/Profile.js文件

module.exports = (sequelize, DataTypes) => {
const Profile = sequelize.define('Profile', {
     files: {
      type: DataTypes.JSON
     },
     fullname: {
       type: DataTypes.STRING,
       allowNull: false
     },
     brandname: DataTypes.STRING,
     skill1: DataTypes.STRING,
     skill2: DataTypes.STRING,
     skill3: DataTypes.STRING,
     skill4: DataTypes.STRING,
     socail_handle1: DataTypes.STRING,
     socail_handle2: DataTypes.STRING
 })
 return Profile 
 }

我希望任何人都可以帮助我解决这个问题!!!

这是我的route.js文件

const AuthController = require('./controllers/AuthController')
const AuthControllerPolicy = require('./policies/AuthControllerPolicy')
const ProfileControler = require('./controllers/ProfileController')
const upload = require ('multer')

module.exports = (app) => {
app.post('/register',
    AuthControllerPolicy.register,
    AuthController.register)

app.post('/login',
    AuthController.login)

app.get('/profile',
    ProfileControler.index)
    
app.post('/upload', upload.single('file'),
    ProfileControler.upload)

}

标签: javascriptvue.jsexpressmulter

解决方案


我注意到两件事:

  1. 您没有将 multer 用作中间件功能

upload.single('file')返回一个函数,该函数应作为 Express 路由中的中间件传递。你可以在你的route.js

const multer = require('multer');

const upload = multer({
  dest: '../public',
  fileFilter,
});

app.post('/upload', upload.single('file'), ProfileController.post);

然后你可以在你的 post 函数中删除上传代码:

module.exports.post = async (req, res) => {
  // Multer makes your file available at req.file
  const file = req.file;

  try {
    // Don't need to await when creating a new Mongo object
    const profile = new Profile({
      profile: this.profile,
      files: file
    });

    // Refactored this to use async/await instead of promises.
    // Avoid mixing promises with async/await.
    const result = await profile.save();
    return res.status(201).json({ message: "Done upload!" });
  } catch (error) {
    console.log(error)
    return res.status(500).send({ error: 'An Error has occured trying to fetch' });
  }
}
  1. 传递给 multer 的文件输入的名称与前端不匹配

您正在配置 multer 以查找名为files:的文件输入upload.single('files'),但在前端您将其命名为file(单数):formData.append('file', this.files)。通常 multer 然后会抛出一个意想不到的字段错误。确保这两个完全匹配。

这个在 Node.js 中解析请求的免费指南将帮助您在 Node.js 中处理文件上传。


推荐阅读