XMLHttpRequest() 不发送 FormData() 导致空 PHP $_FILES 数组并且没有文件上传
XMLHttpRequest() not sending FormData() resulting in empty PHP $_FILES array and no file uploaded
我想做什么:
本质上,我试图将文件上传到服务器上用户通过 HTML <input type="file">
元素上传的目录。
为此,我在 <input>
元素的 change
事件上创建了一个新的 XMLHttpRequest
,它将上传文件的数据发送到 upload.php
文件然后会处理上传的文件并异步上传到服务器。
我的代码:
HTML
<form class="js-upload-form" method="POST" action="upload.php" enctype="multipart/form-data">
<input class="button js-uploaded-file" type="file" name="file" />
</form>
JS
document.querySelector('.js-uploaded-file').addEventListener('change', function() {
let file = this.files[0];
let formData = new FormData();
formData.append('file', file);
let xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.php', true);
xhr.setRequestHeader('Content-type', 'multipart/form-data');
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
let percentComplete = (e.loaded / e.total) * 100;
console.log(percentComplete + '% uploaded');
}
};
xhr.onload = function() {
if (this.status == 200) {
console.info(this.response);
}
};
xhr.send(formData);
}, false);
PHP (upload.php)
print_r($_FILES);
$currentDir = getcwd();
$uploadDirectory = "/uploads/";
$errors = []; // Store all foreseen and unforseen errors here
$fileName = preg_replace("/[^A-Z0-9._-]/i", "_", $_FILES['file']['name']);
$fileSize = $_FILES['file']['size'];
$fileTmpName = $_FILES['file']['tmp_name'];
$fileType = $_FILES['file']['type'];
$uploadPath = $currentDir . $uploadDirectory . $fileName;
if ($fileSize > 2000000) {
$errors[] = "This file is more than 2MB. Sorry, it has to be less than or equal to 2MB";
}
if (empty($errors)) {
$didUpload = move_uploaded_file($fileTmpName, $uploadPath);
if ($didUpload) {
echo "The file " . basename($fileName) . " has been uploaded";
} else {
echo "An error occurred somewhere. Try again or contact the admin";
}
} else {
foreach ($errors as $error) {
echo $error . "These are the errors" . "\n";
}
}
我的问题
此代码根本不起作用。打印 $_FILES
数组 returns 一个空数组,并在控制台记录 xhr.response
记录在 PHP ('An error occurred somewhere. Try again or contact the admin') 中设置的错误消息。我真的很感激任何解决这个问题的帮助,因为我已经浏览了无数关于这个问题的其他在线资源,即使我觉得我的代码完全按照他们所说的去做,它仍然不起作用。
我试过的:
我尝试简单地提交表单而不是尝试使用 FormData()
对象和 <input>
通过添加提交按钮更改事件来提交表单,尽管页面重定向到 ...url/upload.php 并没有异步工作,$_FILES
数组包含上传文件的正确数据并且文件已上传到服务器,这让我觉得我的文件一定有问题Javascript 代码,与 XMLHttpRequest
或 FormData
对象有关。
通常,XMLHttpRequest 将从 FormData 对象生成适当的 Content-Type。
但是,您正在用您手动创建的覆盖它:
xhr.setRequestHeader('Content-type', 'multipart/form-data');
但是,缺少必需的 boundary
属性,因此 PHP 无法找到拆分请求部分的点。
不要覆盖内容类型。删除引用行。
我想做什么:
本质上,我试图将文件上传到服务器上用户通过 HTML <input type="file">
元素上传的目录。
为此,我在 <input>
元素的 change
事件上创建了一个新的 XMLHttpRequest
,它将上传文件的数据发送到 upload.php
文件然后会处理上传的文件并异步上传到服务器。
我的代码:
HTML
<form class="js-upload-form" method="POST" action="upload.php" enctype="multipart/form-data">
<input class="button js-uploaded-file" type="file" name="file" />
</form>
JS
document.querySelector('.js-uploaded-file').addEventListener('change', function() {
let file = this.files[0];
let formData = new FormData();
formData.append('file', file);
let xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.php', true);
xhr.setRequestHeader('Content-type', 'multipart/form-data');
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
let percentComplete = (e.loaded / e.total) * 100;
console.log(percentComplete + '% uploaded');
}
};
xhr.onload = function() {
if (this.status == 200) {
console.info(this.response);
}
};
xhr.send(formData);
}, false);
PHP (upload.php)
print_r($_FILES);
$currentDir = getcwd();
$uploadDirectory = "/uploads/";
$errors = []; // Store all foreseen and unforseen errors here
$fileName = preg_replace("/[^A-Z0-9._-]/i", "_", $_FILES['file']['name']);
$fileSize = $_FILES['file']['size'];
$fileTmpName = $_FILES['file']['tmp_name'];
$fileType = $_FILES['file']['type'];
$uploadPath = $currentDir . $uploadDirectory . $fileName;
if ($fileSize > 2000000) {
$errors[] = "This file is more than 2MB. Sorry, it has to be less than or equal to 2MB";
}
if (empty($errors)) {
$didUpload = move_uploaded_file($fileTmpName, $uploadPath);
if ($didUpload) {
echo "The file " . basename($fileName) . " has been uploaded";
} else {
echo "An error occurred somewhere. Try again or contact the admin";
}
} else {
foreach ($errors as $error) {
echo $error . "These are the errors" . "\n";
}
}
我的问题
此代码根本不起作用。打印 $_FILES
数组 returns 一个空数组,并在控制台记录 xhr.response
记录在 PHP ('An error occurred somewhere. Try again or contact the admin') 中设置的错误消息。我真的很感激任何解决这个问题的帮助,因为我已经浏览了无数关于这个问题的其他在线资源,即使我觉得我的代码完全按照他们所说的去做,它仍然不起作用。
我试过的:
我尝试简单地提交表单而不是尝试使用 FormData()
对象和 <input>
通过添加提交按钮更改事件来提交表单,尽管页面重定向到 ...url/upload.php 并没有异步工作,$_FILES
数组包含上传文件的正确数据并且文件已上传到服务器,这让我觉得我的文件一定有问题Javascript 代码,与 XMLHttpRequest
或 FormData
对象有关。
通常,XMLHttpRequest 将从 FormData 对象生成适当的 Content-Type。
但是,您正在用您手动创建的覆盖它:
xhr.setRequestHeader('Content-type', 'multipart/form-data');
但是,缺少必需的 boundary
属性,因此 PHP 无法找到拆分请求部分的点。
不要覆盖内容类型。删除引用行。