[英]VueJS: $_FILES Not Receiving Data from Frontend to Backend
I tried different ways to upload images to SQL, but the problem is that I cannot get the file's data at backend.我尝试了不同的方法将图像上传到 SQL,但问题是我无法在后端获取文件的数据。 Some answers say that it's because the form does not have an enctype but I tried that too.
一些答案说这是因为表单没有 enctype,但我也尝试过。 I'm not sure if it's applicable to Vue since I am using axios.
我不确定它是否适用于 Vue,因为我使用的是 axios。 Also, I tried using uploadFile as a parameter for the axios so $_FILES would also read it as $_GET, because it worked on some of my codes as well.
此外,我尝试使用 uploadFile 作为 axios 的参数,因此 $_FILES 也将其读取为 $_GET,因为它也适用于我的一些代码。 By the way, the submitTestData is in another file in another folder, which is inside a store (VueX).
顺便说一句,submitTestData 位于另一个文件夹中的另一个文件中,该文件夹位于商店 (VueX) 内。 I used dispatch to send the data towards the store so that it would finally send a post method to backend.
我使用 dispatch 将数据发送到 store,以便最终将 post 方法发送到后端。
store.js store.js
submitTestData2 ({ commit }, payload) {
console.log(payload.uploadFile)
return new Promise((resolve, reject) => {
const formData = new FormData()
formData.append('uploadFile', payload.uploadFile)
const config = {
headers: { 'Content-Type': 'multipart/form-data' }
}
axios
.post(
'http://localhost/MyComposer/',
{
token: payload.token,
subject: payload.subject,
timer: payload.timer,
question: payload.question,
answer: payload.answer,
formData
},
{
params: {
submitId: 7,
uploadFile: formData
},
config
}
)
.then(response => {
commit('SAVE_TEST_DATA', response.data)
console.log(response)
resolve(response)
})
.catch(error => {
reject(error)
})
})
},
AddTest.vue添加测试.vue
<q-form class="q-pa-md" align="center">
<h5>Test Creation Form</h5>
<!-- <q-btn label="Add Subject" color="primary" to="/addsub" /> -->
<q-btn label="Return to Main" to="/dashboard" color="primary" />
<q-btn label="View Student Answers" color="primary" to="/subjectntestlist" />
<q-btn label="View Student Profile" color="primary" to="/studentprofile" />
<q-card>
<q-separator />
<q-card-section class="q-gutter-md" align="center">
<q-select
filled
v-model="testItems.subject"
:options="option"
map-options
emit-value
option-value="subjectId"
option-label="subjectName"
label="Choose a Subject"
style="width: 250px"
stack-label
input-debounce="0"
/>
<q-file
filled
v-model="testItems.uploadFile"
label="Upload File Here"
style="width: 500px"
/>
<h5>Timer</h5>
<q-input label="Minute(s)" name="timer" v-model="testItems.timer" style="width: 500px" />
<h5>Question</h5>
<q-input name="question" v-model="testItems.question" style="width: 500px" />
<h5>Answer</h5>
<q-input name="answer" v-model="testItems.answer" style="width: 500px" />
<br />
<q-btn label="Save Test Item" @click="submitTestData" />
</q-card-section>
</q-card>
</q-form>
submitTestData1() {
this.$store
.dispatch("submitTestData2", {
token: this.token,
subject: this.testItems.subject,
question: this.testItems.question,
answer: this.testItems.answer,
uploadFile: this.testItems.uploadFile,
timer: this.testItems.timer
})
.then(response => {
alert("Test was added to the database!");
});
},
<?php
namespace Classes;
use Classes\ConnectDb;
class TestClass
{
public function addTest()
{
$datab = new ConnectDb;
$db = $datab->Connect();
if (isset($_GET['submitId']) && $_GET['submitId'] == 7) {
$testdata = file_get_contents('php://input');
$testdecodedData = json_decode($testdata);
$subject = $testdecodedData->{'subject'};
$access_id = $testdecodedData->{'token'};
$question = $testdecodedData->{'question'};
$answer = $testdecodedData->{'answer'};
// $testImage = $testdecodedData->{'uploadFile'};
$testTimer = $testdecodedData->{'timer'};
$name = $_FILES['uploadFile'];
echo $name;
$testdataDb = array(
'SubjectId' => $subject,
'AccessId' => $access_id,
'Question' => $question,
'Answer' => $answer,
// 'TestImage' => $testImage,
'Timer' => $testTimer * 60
);
$testId = $db->insert('testdetails', $testdataDb);
if ($testId) {
echo 'Test details were added!';
}
}
}
You need to pass header as well like below您需要像下面一样通过 header
submitTestData ({ commit }, payload) {
console.log(payload.uploadFile)
return new Promise((resolve, reject) => {
const formData = new FormData()
formData.append('uploadFile', payload.uploadFile)
const config = {
headers:{'Content-Type' : 'multipart/form-data'}
};
axios
.post('http://localhost/MyComposer/',formData,config)
.then(response => {
commit('SAVE_TEST_DATA', response.data)
console.log(response)
resolve(response)
})
.catch(error => {
reject(error)
})
})
},
It looks like you're not getting the file's name properly from the $_FILES superglobal.看起来您没有从 $_FILES 超全局中正确获取文件名。 You have $_FILES['uploadFile'] in your code however the $_FILES array is structured like this for uploads ( uploadFile represents the name of the file upload input field from your form so this varies by input field name ):
您的代码中有 $_FILES['uploadFile'] 但是 $_FILES 数组的结构类似于上传( uploadFile 代表表单中文件上传输入字段的名称,因此这因输入字段名称而异):
Array
(
[uploadFile] => Array
(
[name] => users_file_name.png
[type] => image/png
[tmp_name] => /path/to/temporary/files/abc123
[error] => 0
[size] => 12345
)
)
So to access the file's name, you need to change the code to this: $_FILES['uploadFile']['name'].因此,要访问文件名,您需要将代码更改为:$_FILES['uploadFile']['name']。
The actual file is stored in a temporary file location on the server so you'll need to grab that temporary file and move it somewhere else on your server.实际文件存储在服务器上的临时文件位置,因此您需要获取该临时文件并将其移动到服务器上的其他位置。 Something like this is what most people do:
大多数人都会这样做:
$temp_file = $_FILES['uploadFile']['tmp_name'];
$target_upload_destination = 'path/to/desired/directory/' . basename($_FILES['uploadFile']['name']);
// Check to see that the file was moved to desired destination successfully
if (move_uploaded_file($temp_file, $target_upload_destination)) {
// do something here
} else {
// Fallback logic here
}
Obviously there should be some logic checks before moving the temp file on your server but, I hope you get the basic idea behind this.显然,在您的服务器上移动临时文件之前应该进行一些逻辑检查,但是,我希望您了解这背后的基本概念。 You should use the file path once it's moved for the DB insert.
为数据库插入移动后,您应该使用文件路径。 I hope this helps.
我希望这有帮助。
There are several problems here both in your client-side and server-side code.在您的客户端和服务器端代码中都有几个问题。
If you want to send a file, you must use a multipart/form-data
request with a FormData
payload.如果要发送文件,则必须使用带有
FormData
有效负载的multipart/form-data
请求。 You appear to be trying to combine a JSON payload with an embedded FormData
which simply won't work.您似乎正在尝试将 JSON 有效负载与嵌入式
FormData
结合起来,这根本不起作用。
You need something like this你需要这样的东西
const formData = new FormData()
Object.entries(payload).forEach(([key, val]) => {
// adds all the properties in "payload" to "formData"
formData.append(key, val)
})
axios.post('http://localhost/MyComposer', formData, {
params: { submitId: 7 }
})
❗ Note that there is no Content-type
header added. ❗ 请注意,没有添加
Content-type
header。 Passing a FormData
instance sets this automatically with the required mime boundaries.传递
FormData
实例会自动将其设置为所需的 mime 边界。
On the PHP side, you would get the token
, subject
, timer
, etc values from $_POST
在 PHP 端,您可以从
$_POST
获取token
、 subject
、 timer
等值
$subject = $_POST['subject'];
$access_id = $_POST['token'];
$question = $_POST['question'];
// etc
The upload file will be available in $_FILES
(seehttps://www.php.net/manual/features.file-upload.post-method.php )上传文件将在
$_FILES
中提供(参见https://www.php.net/manual/features.file-upload.post-method.php )
$uploadFile = $_FILES['uploadFile'];
if (!$uploadFile['error']) {
echo $uploadFile['name'];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.