gpt4 book ai didi

javascript - 尝试将 File 对象作为属性传递给组件并获取空对象。我也想知道这样安全吗?

转载 作者:行者123 更新时间:2023-12-03 01:14:16 26 4
gpt4 key购买 nike

我有一个通用头像预览模式:

<avatar-update :img-file="avatarFile" :show="avatarModalShow" :img-url="url" @close="avatarModalShow = !avatarModalShow" :change-avatar="updateCrop" @destroyUrl="imgUrl = null"> </avatar-update>

当提交头像时,我使用我的 root 将一堆属性发送到 AvatarUpdate 组件。

HTML

<div>
<label for="avatar" class="cursor-pointer thumbnail-link bg-white p-1 rounded-lg" href="">
<img class="thumbnail" src="{{asset('images/avatars/avatar-1.png')}}">
</label>
<input id="avatar" class="hidden" type="file" @change="onFileChange"/>
</div>

onFileChange: function(e) {
const file = e.target.files[0];
this.url = URL.createObjectURL(file);
this.updateCrop = !this.updateCrop;
this.avatarModalShow = !this.avatarModalShow;
this.avatarFile = file;
},

当我在 onFileChange 函数中 console.log 文件 const 时,我得到了文件对象。但是,当我尝试在 AvatarUpdate 组件中输出 {{imgFile}} 属性时,我得到一个空对象。

我想知道这是否安全,以及文件数据是否可以在根组件和 AvatarUpdate 组件之间进行操作?还有什么东西阻止我能够将文件对象作为属性发送和输出吗?为什么它在 AvatarUpdate 组件上给我一个空对象?

我对这么多问题感到抱歉,但我将它们包含在一篇文章中的原因是我认为可能存在一些安全功能阻止我通过组件发送文件对象。

编辑

这是我的 AvatarUpload 组件:

<modal v-show="show" heading="Avatar Preview" @close="close">
<div class="flex flex-col">

<h4 class="text-blue-light mb-5">The avatar will be automatically cropped from the center.</h4>

<div class="flex flex-col items-center">
<img class="w-2/3" :src="imgUrl">
</div>

<p>{{imgFile}}</p>

<button class="mt-4 h-10 self-end text-center bg-third-color hover:bg-secondary-color text-white font-bold py-2 px-4 rounded" v-on:click="submitAvatar()">Submit</button>
</div>

<script>

export default {
props: ['show','imgUrl','changeAvatar','imgFile'],
data() {
return {
image: null,
message: null
}
},
methods: {
close: function(){
this.$emit('close');
},

submitAvatar: function(){
console.log(file);
axios({
method: 'POST',
url: '/profile/avatar',
data: {},
}).then(function (response) {


this.message = "Your avatar has been submitted";

}.bind(this))
.catch(function (error) {
console.log(error);
});
}
}
}
</script>

我已经能够在根实例上的 onFileChange 函数中从 this.url = URL.createObjectURL(file); 获取 blob。我想做的是使用 :img-file="avatarFile" 属性将整个文件对象发送到 AvatarUpdate 组件。

这样我就可以通过 Laravel Controller 中的请求访问的方式发送数据:

submitAvatar: function(){
//Change here!
var data = new FormData()
var file = this.imgFile;
data.append('avatar', file);

axios({
method: 'POST',
url: '/profile/avatar',
data: data,
}).then(function (response) {


this.message = "Your avatar has been submitted";

}.bind(this))
.catch(function (error) {
console.log(error);
});
}

Laravel 用户 Controller

用户 Controller

public function avatar(Request $request)
{
return $request->hasFile('avatar');
}

最佳答案

在您的代码中,this.avatarFile = file是一个File(继承自Blob)对象,它不能用于直接image src(如果打开浏览器检查器,img:src的值为[object File],显然这个值不是你想要的预计)。

您可以使用Javascript MDN: FileReader.readAsDataURL达到目标。

Javascript MDN: URL.createObjectURL()是另一种解决方案,但您必须仔细处理内存管理。检查Javascript MDN: URL.createObjectURL() Usage notes

PS: 我建议首先将 File 对象转换为(data-url 或 object-url),然后将(data-url 或 object-url)传递给子组件。直接传递 File 对象可能会遇到 react 性问题。

一个使用FileReader的简单演示:

Vue.config.productionTip = false
Vue.component('img-preview', {
template: `<div>
<img :src="imageBlob" alt="test"/>
</div>`,
props: ['imageBlob']
})
new Vue({
el: '#app',
data() {
return {
imageObj: null
}
},
methods:{
onFileChange: function(ev) {
const selectFile = ev.target.files[0]
let reader = new FileReader()
reader.readAsDataURL(selectFile)
reader.addEventListener('load', () => {
this.imageObj = reader.result
//console.log('select image', reader.result)
}, false)
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div>
<label for="avatar">
<img-preview :image-blob="imageObj"></img-preview>
</label>
<input id="avatar" class="hidden" type="file" @change="onFileChange($event)"/>
</div>
</div>

一个使用createObjectURL的简单演示:

Vue.config.productionTip = false
Vue.component('img-preview', {
template: `<div>
<img :src="imageBlob" alt="test"/>
</div>`,
props: ['imageBlob']
})
new Vue({
el: '#app',
data() {
return {
imageObj: null
}
},
methods:{
onFileChange: function(ev) {
const selectFile = ev.target.files[0]
this.imageObj = URL.createObjectURL(selectFile)
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div>
<label for="avatar">
<img-preview :image-blob="imageObj"></img-preview>
</label>
<input id="avatar" class="hidden" type="file" @change="onFileChange($event)"/>
</div>
</div>

下面是一个演示(直接将文件对象传递给子组件):

Vue.config.productionTip = false
Vue.component('img-preview', {
template: `<div>{{imageBlob}}
<img :src="internalImageObj" alt="test"/>
</div>`,
props: ['imageBlob'],
data() {
return {
internalImageObj: ''
}
},
watch: {
imageBlob: function (newVal) {
let reader = new FileReader()
reader.readAsDataURL(newVal)
reader.addEventListener('load', () => {
this.internalImageObj = reader.result
}, false)
}
}
})
new Vue({
el: '#app',
data() {
return {
selectedFile: null
}
},
methods:{
onFileChange: function(ev) {
this.selectedFile = ev.target.files[0]
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div>
<label for="avatar">
<img-preview :image-blob="selectedFile"></img-preview>
</label>
<input id="avatar" class="hidden" type="file" @change="onFileChange($event)"/>
</div>
</div>

关于javascript - 尝试将 File 对象作为属性传递给组件并获取空对象。我也想知道这样安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52087596/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com