Проблема с загрузкой файла во внешнем интерфейсе Vue

#vue.js #upload

Вопрос:

Когда я пытаюсь загрузить фотографию пользователя с помощью Vue, FormData просто кажется пустым объектом. Затем происходит сбой промежуточного программного обеспечения Multer из-за отсутствия запроса.файл для его чтения.

User.vue

 <form enctype="multipart/form-data">
   <div class="pl-3 label">User Photo</div>
   <v-file-input
      accept='image/*'
      label="Upload Photo"
      v-model="photo"
    ></v-file-input>
    <v-btn class="mr-5" color="blue lighten-3" @click="submit">
        save changes
    </v-btn>

export default {
  data: () => ({
    photo: null
  }),
  methods: {
    submit() {
      let formData = new FormData();
      if (this.photo) {
        formData.append('photo', this.photo)
      }
      this.$store.dispatch('updateMe', {
        photo: formData
      });
    }
  }
};
 

Хранилище Vuex

 export default new Vuex.Store({
  state: {
    photo: null
  },
  mutations: {
    setUpdatedUser(state, payload) {
      state.name = payload.name;
      state.email = payload.email;
      state.photo = payload.photo;
    }
  },
  actions: {
    async updateMe({ commit, getters }, payload) {
      let id = localStorage.getItem('userId');
      let user = {
        photo: payload.photo
      };
      try {
        let token = getters.token;
        const response = await axios.patch(
          `http://localhost:3000/api/v1/users/updateMe`,
          user,
          {
            headers: { Authorization: 'Bearer '   token }
          }
        );
        commit('setUpdatedUser', response.data.updatedUser);
      } catch (err) {
        console.log(err);
      }
    }
  }
 

Пользовательский контроллер

 const multerStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'public/users');
  },
  filename: (req, file, cb) => {
    console.log(file)
    const ext = file.mimetype.split('/')[1];
    cb(null, `user-${req.user.id}-${Date.now()}.${ext}`);
  }
});

const multerFilter = (req, file, cb) => {
  if (file.mimetype.startsWith('image')) {
    cb(null, true);
  } else {
    cb(new AppError('Not an image. Please upload only images.', 400), false);
  }
};

const upload = multer({
  storage: multerStorage,
  fileFilter: multerFilter
});

exports.uploadUserPhoto = upload.single('photo');
 

Большинство других примеров, с которыми я сравнивал, не используют v-model для привязки ввода. Имеет ли это значение?

Ответ №1:

В приложении, в котором я обрабатываю загрузку файлов, файлы отправляются на серверную часть узла.
Я также v-model в своем компоненте, так что это не должно быть проблемой.

Метод внешнего интерфейса:

 upload() {
  const data = new FormData()
  data.append('file', this.file, this.file.name) // Filename is optional
  data.append('additionalInformation', this.additionalInformation)

  axios.
    post('/api/v1/upload/', data)
    .then(response => /* response handling */)
    .catch(error => /* error handling */)

}
 

Конечная точка узла выглядит следующим образом:

 app.post('/api/v1/upload/', multer().single('file'), (request, response) => {
  upload(request.body, request.file, response, config)
})
 

Ссылка: FormData.append()