javascript - Hur man skickar en fil från ett formulär med Axios
Genom att använda rå HTML när jag postar en fil till en Flask-server med följande kan jag få åtkomst till filer från Flask-requestens globala:
<form id="uploadForm" action='upload_file' role="form" method="post" enctype=multipart/form-data>
<input type="file" id="file" name="file">
<input type=submit value=Upload>
</form>
I kolven:
def post(self):
if 'file' in request.files:
# ....
När jag försöker göra samma sak med Axios är Flask-begärans globala objekt tomt:
<form id="uploadForm" enctype="multipart/form-data" v-on:change="uploadFile">
<input type="file" id="file" name="file">
</form>
<script>
function uploadFile(event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
</script>
Om jag använder samma uploadFile-funktion ovan men tar bort headers json från axios.post-metoden får jag i form-nyckeln i mitt Flask-förfrågningsobjekt en CSV-lista med strängvärden (filen är en .csv).
Hur kan jag få ett filobjekt skickat via axios?
Svar #1
Lägg till filen i ett formData-objekt och ange Content-Type-huvudet till multipart/form-data.
var formData = new FormData();
var imagefile = document.querySelector('#file');
formData.append("image", imagefile.files[0]);
axios.post('upload_file', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
Svar #2
Exempel på applikation som använder Vue. Kräver en backendserver som körs på localhost för att bearbeta förfrågan:
var app = new Vue({
el: "#app",
data: {
file: ''
},
methods: {
submitFile() {
let formData = new FormData();
formData.append('file', this.file);
console.log('>> formData >> ', formData);
// You should have a server side REST API
axios.post('http://localhost:8080/restapi/fileupload',
formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}
).then(function () {
console.log('SUCCESS!!');
})
.catch(function () {
console.log('FAILURE!!');
});
},
handleFileUpload() {
this.file = this.$refs.file.files[0];
console.log('>>>> 1st element in files array >>>> ', this.file);
}
}
});
https://codepen.io/pmarimuthu/pen/MqqaOE
Svar #3
Om du inte vill använda ett FormData-objekt (t.ex. om ditt API kräver specifika content-type-signaturer och multipart/formdata inte är en av dem) kan du göra så här istället:
uploadFile: function (event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': file.type
}
})
}
Svar #4
Dela min erfarenhet med React och HTML-input
Definiera inmatningsfält
<input type="file" onChange={onChange} accept ="image/*"/>
Definiera onChange-lyssnare
const onChange = (e) => {
let url = "https://<server-url>/api/upload";
let file = e.target.files[0];
uploadFile(url, file);
};
const uploadFile = (url, file) => {
let formData = new FormData();
formData.append("file", file);
axios.post(url, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
}).then((response) => {
fnSuccess(response);
}).catch((error) => {
fnFail(error);
});
};
const fnSuccess = (response) => {
//Add success handling
};
const fnFail = (error) => {
//Add failed handling
};
Svar #5
Detta fungerar för mig, jag hoppas att det hjälper någon.
var frm = $('#frm');
let formData = new FormData(frm[0]);
axios.post('your-url', formData)
.then(res => {
console.log({res});
}).catch(err => {
console.error({err});
});
