问题
I am trying to upload image to the server and the same time to pass some additional data (in the same post request) using: VueJS 2 (CLI 3), axios, multer, sharp and I have NodeJS with MongoDB in the backend.
Front-end:
<form @submit.prevent="onSubmit" enctype="multipart/form-data">
<div class="input">
<label for="name">Name: </label>
<input
type="text"
id="name"
v-model="name">
</div>
<div class="input">
<label for="last_name">Your last_name: </label>
<input
type="text"
id="last_name"
v-model="last_name">
</div>
<div class="input">
<label for="permalink">permalink</label>
<input
type="text"
id="permalink"
v-model="permalink">
</div>
<div class="input">
<label for="price">price</label>
<input
type="text"
id="price"
v-model="price">
</div>
<div class="input">
<label for="photo">photo</label>
<input
style="display: none"
type="file"
id="photo"
@change="onFileSelected"
ref="fileInput">
<div @click="$refs.fileInput.click()">Pick file</div>
</div>
<div class="submit">
<md-button type="submit" class="md-primary md-raised">Submit</md-button>
</div>
</form>
VueJS methods:
import axios from 'axios'
export default {
data () {
return {
name: '',
last_name: '',
permalink: '',
selectedFile: null,
url: null,
price: 0,
second: false
}
},
methods: {
onFileSelected (event) {
this.selectedFile = event.target.files[0]
this.url = URL.createObjectURL(this.selectedFile)
},
onUpload () {
const fd = new FormData()
fd.append('image', this.selectedFile, this.selectedFile.name)
axios.post('http...', fd, {
onUploadProgress: uploadEvent => {
console.log('Upload Progress ' + Math.round(uploadEvent.loaded / uploadEvent.total * 100) + ' %')
}
})
.then(res => {
console.log(res)
})
},
onSubmit () {
const fd = new FormData()
fd.append('image', this.selectedFile, this.selectedFile.name)
fd.append('data', this.name, this.last_name)
axios.post('http://localhost:7000/api/create-user', fd, {
onUploadProgress: uploadEvent => {
console.log('Upload Progress ' + Math.round(uploadEvent.loaded / uploadEvent.total * 100) + ' %')
}
})
.then(res => {
console.log(res)
if (res.data === 'ok') {
this.second = true
}
})
.then(
setTimeout(function () {
this.second = false
this.reset()
}.bind(this), 2000)
)
.catch(error => console.log(error))
}
}
}
NodeJS:
controller.postCreateUser = (req, res) => {
const sharp = require('sharp');
const fs = require('fs');
const folderImg = 'backend/uploads/';
console.log(JSON.stringify(req.body));
console.log(req.file);
res.send("ok");
};
The results of req.file is (which is good):
{ fieldname: 'image',
originalname: 'musk.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: 'backend/uploads/original/',
filename: 'musk-1545470459038.jpg',
path: 'backend\\uploads\\original\\musk-1545470459038.jpg',
size: 108787 }
The results of console.log(req.body) is
{"data":""}
The problem is here data has empty string and I don't receive any data. I need having the data to store to my database. How to do that?
If something isn't very clear to you, ask me for more details.
回答1:
In your onSubmit method, you do this:
const fd = new FormData()
fd.append('image', this.selectedFile, this.selectedFile.name)
fd.append('data', this.name, this.last_name)
But FormData.append() expects these parameters:
name- The name of the field whose data is contained in value.value- The field's value. This can be a USVString or Blob (including subclasses such as File).filenameOptional - The filename reported to the server (a USVString), when a Blob or File is passed as the second parameter.
The third parameter does not apply on this line: fd.append('data', this.name, this.last_name)
Instead, you can do either of these:
fd.append('data', `${this.name} ${this.last_name}`) // Send a single String
or
// Send both Strings separately
fd.append('name', this.name)
fd.append('last_name', this.last_name)
or
// Send the data as JSON
fd.append('data', JSON.stringify({name: this.name, last_name: this.last_name}))
来源:https://stackoverflow.com/questions/53894691/vuejs-upload-image-with-additional-data