使用 Laravel 后端的 Vue-resource + FormData 文件上传
Vue-resource + FormData File Upload with Laravel Backend
我已经在 VueJS 论坛上提出了我的问题:https://forum.vuejs.org/t/file-upload-with-formdata-vue-resource/20952/3
但是!为了重复我的成功机会,我会问你我的问题。
只是我有一个输入类型文件(没有表单父节点),我正在尝试将一个带有 FormData 和 Vue-resource http 的文件异步上传到我的 Laravel 5.5 API 后端..
为了测试我的上传,我的控制器 return 一个 JSON 响应转储了我的 $request。
好吧,我有一个 200 代码,但不幸的是我的回复是空的..
感谢您的帮助:)
Request payload here
客户代码
export default {
name: 'profile',
data () {
return {
user: {},
files: [],
filepath: false,
imageData: ''
}
},
mounted () {
this.user = this.$store.getters.user
},
methods: {
reset: function () {
this.remove()
},
upload: function (e) {
var data = new FormData()
var file = this.files[0]
data.append('test', 1234)
data.append('avatar', file)
this.$http({
url: this.user.actions.updateAvatar,
body: data,
method: 'POST',
responseType: 'json',
before: function (request) {
console.log(request)
}
})
.then((response) => {
console.log(response)
})
.catch((errorResponse) => {
console.log(errorResponse)
})
},
sync: function (e) {
e.preventDefault()
this.files = e.target.files || e.dataTransfer.files
if (!this.files.length) {
return
}
this.createFile(e, this.files[0])
},
createFile: function (e, file) {
this.filepath = URL.createObjectURL(file)
},
remove: function () {
URL.revokeObjectURL(this.filepath)
this.filepath = false
this.files = []
document.getElementById('avatar').value = ''
}
}
}
<template>
<!-- header profile -->
<div id="profile">
<section class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="profile">
<input type="hidden" name="_method" value="PUT"/>
<header>
<label for="avatar" class="avatar" v-if="!filepath">
<img :src="user.avatar || 'http://placehold.it/50x50'" alt="avatar">
</label>
<div class="avatar" @click="reset" v-if="filepath">
<img :src="filepath" alt="avatar">
</div>
<!-- Trigger a preview -->
<input @change="sync" id="avatar" name="avatar" type="file" accept="image/*;" class="hide">
<div class="info">
<span class="name">John Snow
<router-link :to="{ name: 'UserSettings' }">
<span class="ico gear"></span>
</router-link>
</span>
<span class="desc">Une bio de 40 caractères</span>
<span class="social">
<span class="ico fb"></span>
<span class="ico tw"></span>
</span>
</div>
</header>
<!-- Trigger upload -->
<span @click="upload" class="btn-save" v-if="filepath">
Enregistrer
</span>
</div>
</div>
<div class="col-lg-8 col-lg-offset-2">
<div class="col-lg-12">
<router-link :to="{ name: 'UserPosts' }">
<span for="dechet" class="nb-dechet">122 déchêts postés</span>
</router-link>
|
<router-link :to="{ name: 'UserBookmarks' }">
<span for="dechet" class="nb-dechet">122 déchêts sauvegardés</span>
</router-link>
|
<router-link :to="{ name: 'UserTrophies' }">
<span for="reward" class="nb-dechet">1 trophé obtenu</span>
</router-link>
</div>
</div>
</div>
</section>
<hr>
<!-- posts -->
<section class="container">
<div class="row">
<router-view></router-view>
</div>
</section>
</div>
</template>
服务器端代码
Route | Dummy Controller
您的代码没有任何问题,只是 response()->json()
无法将 Illuminate\Http\UploadedFile
转换为 json。
您的文件正在上传中,请尝试查看
return response()->json([
'avatar' => $request->file('avatar')->getClientOriginalName()
]);
您将在响应中得到文件的名称。
原因
无法将 Illuminate\Http\UploadedFile
转换为 JSON 响应的原因是它没有实现 Illuminate\Contracts\Support\Jsonable
我已经在 VueJS 论坛上提出了我的问题:https://forum.vuejs.org/t/file-upload-with-formdata-vue-resource/20952/3
但是!为了重复我的成功机会,我会问你我的问题。
只是我有一个输入类型文件(没有表单父节点),我正在尝试将一个带有 FormData 和 Vue-resource http 的文件异步上传到我的 Laravel 5.5 API 后端..
为了测试我的上传,我的控制器 return 一个 JSON 响应转储了我的 $request。
好吧,我有一个 200 代码,但不幸的是我的回复是空的..
感谢您的帮助:)
Request payload here
客户代码
export default {
name: 'profile',
data () {
return {
user: {},
files: [],
filepath: false,
imageData: ''
}
},
mounted () {
this.user = this.$store.getters.user
},
methods: {
reset: function () {
this.remove()
},
upload: function (e) {
var data = new FormData()
var file = this.files[0]
data.append('test', 1234)
data.append('avatar', file)
this.$http({
url: this.user.actions.updateAvatar,
body: data,
method: 'POST',
responseType: 'json',
before: function (request) {
console.log(request)
}
})
.then((response) => {
console.log(response)
})
.catch((errorResponse) => {
console.log(errorResponse)
})
},
sync: function (e) {
e.preventDefault()
this.files = e.target.files || e.dataTransfer.files
if (!this.files.length) {
return
}
this.createFile(e, this.files[0])
},
createFile: function (e, file) {
this.filepath = URL.createObjectURL(file)
},
remove: function () {
URL.revokeObjectURL(this.filepath)
this.filepath = false
this.files = []
document.getElementById('avatar').value = ''
}
}
}
<template>
<!-- header profile -->
<div id="profile">
<section class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="profile">
<input type="hidden" name="_method" value="PUT"/>
<header>
<label for="avatar" class="avatar" v-if="!filepath">
<img :src="user.avatar || 'http://placehold.it/50x50'" alt="avatar">
</label>
<div class="avatar" @click="reset" v-if="filepath">
<img :src="filepath" alt="avatar">
</div>
<!-- Trigger a preview -->
<input @change="sync" id="avatar" name="avatar" type="file" accept="image/*;" class="hide">
<div class="info">
<span class="name">John Snow
<router-link :to="{ name: 'UserSettings' }">
<span class="ico gear"></span>
</router-link>
</span>
<span class="desc">Une bio de 40 caractères</span>
<span class="social">
<span class="ico fb"></span>
<span class="ico tw"></span>
</span>
</div>
</header>
<!-- Trigger upload -->
<span @click="upload" class="btn-save" v-if="filepath">
Enregistrer
</span>
</div>
</div>
<div class="col-lg-8 col-lg-offset-2">
<div class="col-lg-12">
<router-link :to="{ name: 'UserPosts' }">
<span for="dechet" class="nb-dechet">122 déchêts postés</span>
</router-link>
|
<router-link :to="{ name: 'UserBookmarks' }">
<span for="dechet" class="nb-dechet">122 déchêts sauvegardés</span>
</router-link>
|
<router-link :to="{ name: 'UserTrophies' }">
<span for="reward" class="nb-dechet">1 trophé obtenu</span>
</router-link>
</div>
</div>
</div>
</section>
<hr>
<!-- posts -->
<section class="container">
<div class="row">
<router-view></router-view>
</div>
</section>
</div>
</template>
服务器端代码
Route | Dummy Controller
您的代码没有任何问题,只是 response()->json()
无法将 Illuminate\Http\UploadedFile
转换为 json。
您的文件正在上传中,请尝试查看
return response()->json([
'avatar' => $request->file('avatar')->getClientOriginalName()
]);
您将在响应中得到文件的名称。
原因
无法将 Illuminate\Http\UploadedFile
转换为 JSON 响应的原因是它没有实现 Illuminate\Contracts\Support\Jsonable