Laravel Vue 多张图片上传失败,每个图片都有一个 NULL 值
Posted
技术标签:
【中文标题】Laravel Vue 多张图片上传失败,每个图片都有一个 NULL 值【英文标题】:Laravel Vue Multiple image Upload failing on for each with a NULL value 【发布时间】:2020-12-27 09:44:08 【问题描述】:我正在尝试在 Laravel 中上传多张图片,但是,一是无法在 html 附带的上传对话框中上传多个图片,二是在 foreach 之前的转储和死机测试中,我得到一个 NULL价值。我是 Laravel 和 vue 的新手,所以我确信这是一个简单的问题,但对于我的生活,我不知道我错过了什么。首先,我在 web.php 文件中运行 post 请求,我不确定这是否是一个好主意。无论如何,我的脚本在我上传文件之前就失败了。 这是我到目前为止的代码。
web.php
Route::post('/upload', function (Request $request)
$uploadedFiles = $request->pics;
foreach ($uploadedFiles as $file)
dd($file);
$file->store('dummy');
return response(['status' => 'success'], 200);
);
app.js(没有我觉得无关紧要的代码)
require("./bootstrap");
window.Vue = require("vue");
import Form, HasError, AlertError from "vform";
window.Form = Form;
Vue.component(HasError.name, HasError);
Vue.component(AlertError.name, AlertError);
import VueRouter from "vue-router";
Vue.use(VueRouter);
let routes = [
path: "/dashboard",
component: require("./components/Dashboard.vue").default
,
path: "/users",
component: require("./components/Users.vue").default
,
path: "/tasks",
component: require("./components/Tasks.vue").default
];
const router = new VueRouter(
mode: "history",
routes
);
Vue.component(
"dashboard-component",
require("./components/Dashboard.vue").default
);
Vue.component("file-upload", require("./components/FileUpload.vue").default);
const app = new Vue(
el: "#app",
router
);
文件上传.vue
<template>
<div>
<input class="" type="file" @change="fieldChange" />
<button class="btn btn-success float-right mt-3" @click="uploadFile">
Upload
</button>
</div>
</template>
<script>
export default
data()
return
attachments: [],
formImage: new FormData()
;
,
methods:
fieldChange(e)
e.preventDefault();
let selectedFiles = e.target.files;
if (!selectedFiles.length)
return false;
for (let i = 0; i < selectedFiles.length; i++)
this.attachments.push(selectedFiles[i]);
console.log(this.attachments);
,
uploadFile()
this.formImage.append("task_image", this.attachments);
const config =
headers: "Content-Type": "multipart/form-data"
;
axios
.post("/upload", this.formImage, config)
.then(response =>
// success
)
.catch(response =>
// fail
);
,
mounted()
console.log("Component mounted.");
;
</script>
Task.vue(完整的。我不知道这里是否有什么东西导致了冲突,所以我包括了所有内容)。
<template>
<div class="custom-container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div
class="card-header text-white"
style="background-color: #605ca8;"
>
<h3 class="card-title">Tasks</h3>
<div class="card-tools">
<button class="btn btn-success" @click="newModal">
<i class="fas fa-tasks"></i> Add New Task
</button>
<!-- <div class="input-group input-group-sm" style="width: 150px;">
<div class="input-group-append"></div>
</div>-->
</div>
</div>
<!-- /.card-header -->
<div
class="table-x-y card-body table-responsive p-0"
style="max-height: 600px;"
>
<table class="table table-hover text-wrap">
<thead>
<tr>
<th>Task</th>
<th>Priority</th>
<th>Assigned To</th>
<th>Assigned By</th>
<th>Date Assigned</th>
<th>Due By:</th>
<th>Task Desc.</th>
<th>Images</th>
<!-- <th>Notes</th> -->
<th>finished</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="task in tasks" :key="task.id">
<td> task.task_name </td>
<td> task.task_priority </td>
<td> task.task_assigned_to </td>
<td> task.task_assigned_by </td>
<td> task.created_at </td>
<td>
task.task_to_be_completed_date
</td>
<td
style="min-width: 300px; max-width: 301px;"
>
task.task_description
</td>
<td>
<img
style="max-width: 150px;"
src="/img/molding.jpg"
alt
/>
task.task_image
</td>
<!-- <td> task.task_notes </td> -->
<td> task.task_finished </td>
<td> task.task_status </td>
<td>
<a
href="#"
class="badge badge-primary p-2 mb-3"
@click="editModal(task)"
>
<i class="fa fa-edit"></i> Edit
</a>
<a
@click="deleteTask(task.id)"
href="#"
class="badge badge-danger p-2"
>
<i class="fa fa-trash"></i> Delete
</a>
<file-upload></file-upload>
</td>
</tr>
</tbody>
</table>
</div>
<!-- /.card-body -->
</div>
</div>
</div>
<form @submit.prevent="editmode ? updateTask() : createTask()">
<!-- Modal -->
<div
class="modal fade"
id="addNew"
tabindex="-1"
aria-labelledby="addNewLabel"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5
class="modal-title"
v-show="!editmode"
id="addNewLabel"
>
Add New Task
</h5>
<h5
class="modal-title"
v-show="editmode"
id="addNewLabel"
>
Update Task Information
</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<input
id="task_name"
type="text"
v-model="form.task_name"
name="task_name"
class="form-control"
placeholder="Task Name"
:class="
'is-invalid': form.errors.has(
'task_name'
)
"
/>
<has-error
:form="form"
field="task_name"
></has-error>
</div>
<div class="form-group">
<select
id="task_priority"
type="text"
v-model="form.task_priority"
name="task_priority"
class="form-control"
:class="
'is-invalid': form.errors.has(
'task_priority'
)
"
>
<option value
>Select a Priority Level</option
>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<has-error
:form="form"
field="task_priority"
></has-error>
</div>
<div class="form-group">
<input
id="task_description"
type="text"
v-model="form.task_description"
name="task_description"
class="form-control"
placeholder="Task Description"
:class="
'is-invalid': form.errors.has(
'task_description'
)
"
/>
<has-error
:form="form"
field="task_description"
></has-error>
</div>
<div class="form-group">
<input
id="task_assigned_by"
type="text"
v-model="form.task_assigned_by"
name="task_assigned_by"
class="form-control"
placeholder="Assigned By"
:class="
'is-invalid': form.errors.has(
'task_assigned_by'
)
"
/>
<has-error
:form="form"
field="task_assigned_by"
></has-error>
</div>
<div class="form-group">
<input
id="task_assigned_to"
type="text"
v-model="form.task_assigned_to"
name="task_assigned_to"
class="form-control"
placeholder="Assigned To"
:class="
'is-invalid': form.errors.has(
'task_assigned_to'
)
"
value="form.user.id"
/>
<has-error
:form="form"
field="task_assigned_to"
></has-error>
</div>
<div class="form-group">
<label for="task_to_be_completed_date"
>Due:</label
>
<input
id="task_to_be_completed_date"
type="date"
v-model="form.task_to_be_completed_date"
name="task_to_be_completed_date"
class="form-control"
placeholder="Due: "
:class="
'is-invalid': form.errors.has(
'task_to_be_completed_date'
)
"
/>
<has-error
:form="form"
field="task_to_be_completed_date"
></has-error>
</div>
<div class="form-group">
<select
id="task_status"
type="text"
v-model="form.task_status"
name="task_status"
class="form-control"
:class="
'is-invalid': form.errors.has(
'task_status'
)
"
>
<option value>Select Task Status</option>
<option value="Pending">Pending</option>
<option value="Finished">Finished</option>
<option value="Incomplete"
>Incomplete</option
>
</select>
<has-error
:form="form"
field="task_status"
></has-error>
</div>
<!-- <div class="form-group">
<input
id="task_notes"
type="text"
v-model="form.task_notes"
name="task_notes"
class="form-control"
placeholder="Notes"
:class="
'is-invalid': form.errors.has(
'task_notes')
"
/>
<has-error :form="form" field="task_notes"></has-error>
</div>-->
<div class="form-group">
<select
id="task_finished"
type="text"
v-model="form.task_finished"
name="task_finished"
class="form-control"
:class="
'is-invalid': form.errors.has(
'task_finished'
)
"
>
<option value
>Select finished status</option
>
<option value="1">Finished</option>
<option value="0">Unfinished</option>
</select>
<has-error
:form="form"
field="task_status"
></has-error>
</div>
<!-- <div class="form-group">
<input id="upload-file" class="form-control" type="file" @change="fieldChange" />
<button class="btn btn-success float-right mt-3" @click="uploadFile">Upload</button>
</div>-->
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-primary"
data-dismiss="modal"
>
Close
</button>
<button
v-show="editmode"
type="submit"
class="btn btn-success"
>
Update
</button>
<button
v-show="!editmode"
type="submit"
class="btn btn-primary"
>
Create New Task
</button>
</div>
</div>
</div>
</div>
</form>
</div>
</template>
<script>
export default
data()
return
editmode: true,
tasks: ,
attachments: [],
formImage: new FormData(),
form: new Form(
id: "",
task_name: "",
task_description: "",
task_assigned_by: "",
task_assigned_to: "",
task_to_be_completed_date: "",
task_priority: "",
// task_notes: "",
task_status: "",
task_finished: ""
// task_image: "",
)
;
,
methods:
updateTask()
this.$Progress.start();
this.form
.put("api/task/" + this.form.id)
.then(() =>
// successfull
$("#addNew").modal("hide");
Swal.fire(
"Updated",
"Task information updated.",
"success"
);
this.$Progress.finish();
Fire_event.$emit("AfterCreate");
)
.catch(() =>
// Unsuccessfull
this.$Progress.fail();
);
,
editModal(task)
this.editmode = true;
this.form.reset();
$("#addNew").modal("show");
this.form.fill(task);
,
newModal()
this.editmode = false;
this.form.reset();
$("#addNew").modal("show");
,
deleteTask(id)
Swal.fire(
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete it!"
).then(result =>
// Send request to the server
if (result.value)
this.form
.delete("api/task/" + id)
.then(() =>
Swal.fire(
"Deleted!",
"Task has been deleted.",
"success"
);
Fire_event.$emit("AfterCreate");
)
.catch(() =>
Swal.fire(
"Failed",
"Something went wrong.",
"warning"
);
);
);
,
loadTasks()
axios.get("api/task").then(( data ) => (this.tasks = data.data));
,
createTask()
this.$Progress.start();
this.form
.post("api/task")
.then(() =>
Fire_event.$emit("AfterCreate");
$("#addNew").modal("hide");
toast.fire(
icon: "success",
title: "Task Created successfully"
);
this.$Progress.finish();
this.target.reset();
)
.catch(() =>
this.$Progress.fail();
// toast.fire(
// icon: "error",
// title: "The Task was not created.",
// );
);
,
created()
this.loadTasks();
// setInterval(() => this.loadUsers(), 3000);
Fire_event.$on("AfterCreate", () =>
this.loadTasks();
);
,
mounted()
console.log("Component mounted.");
;
</script>
对此的任何帮助将不胜感激。我正在尝试在本地上传到我的 sql 服务器。在我的 .env 文件中,我指定了 FILESYSTEM_DRIVER=public 指向该文件中预先指定的 config/filesystem.php 公共路由。
【问题讨论】:
【参考方案1】:这里有几个问题
您正在阻止 <input type="file">
上的 change 事件的默认事件操作。不要那样做。从您的fieldChange
方法中删除此行
e.preventDefault()
Content-type
请求的 multipart/form-data
标头还需要包含 mime-boundary 标记。这些是在使用 FormData
时由浏览器自动添加的,因此您不应手动设置它们。将您的 Axios 调用更改为
axios.post("/upload", this.formImage) // no config required
您正在将一组文件添加到您的FormData
。这不是您添加多个文件的方式。相反,您必须多次调用append()
。向 PHP 发布数组数据时,字段名称也应以[]
为后缀
this.attachments.forEach(file =>
this.formImage.append("task_image[]", file)
)
见https://www.php.net/manual/features.file-upload.multiple.php
您的 PHP 代码应该在请求文件中寻找 task_image
,而不是 pics
$uploadedFiles = $request->file('task_image');
// or maybe
$uploadedFiles = $request->task_image;
// I don't know Laravel and the docs are useless for multiple file uploads
【讨论】:
谢谢菲尔。我实施了建议的更改,但仍然收到“为 foreach() 提供的参数无效”错误。我被难住了。 我根本不了解 Laravel,所以也许你需要$uploadedFiles = $request->task_image;
这有点帮助。错误改了哈哈哈。现在我得到:消息:“调用字符串上的成员函数 store()” 在我的 dd() 调用中,我得到了绿色的 object_file。 :)以上是关于Laravel Vue 多张图片上传失败,每个图片都有一个 NULL 值的主要内容,如果未能解决你的问题,请参考以下文章