XMLHttpRequest()未发送FormData()导致空的PHP $ _FILES数组且未上传文件

时间:2019-02-28 12:13:44

标签: javascript php forms xmlhttprequest asyncfileupload

我要做什么:

本质上,我试图将文件上传到用户通过HTML <input type="file">元素上传的服务器上的目录中。

为此,我正在XMLHttpRequest元素的<input>事件上创建一个新的change,该事件应将上传文件的数据发送到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数组将返回一个空数组,控制台记录xhr.response会记录PHP中设置的错误消息(“某处发生错误。请重试或联系管理员”)。我非常感谢解决此问题的任何帮助,因为我浏览了无数其他有关此问题的在线资源,即使我觉得我的代码完全按照他们的意愿去做,但仍然行不通。

我尝试过的事情:

我尝试仅提交表单,而不尝试通过添加提交按钮来使用FormData()对象和<input>更改事件来提交表单,尽管页面已重定向到... url / upload.php并且无法异步工作,$_FILES数组包含上载文件的正确数据,并且该文件已上载到服务器,这使我认为我的Javascript代码中肯定存在问题,无论是与{ {1}}或XMLHttpRequest对象。

1 个答案:

答案 0 :(得分:1)

通常,XMLHttpRequest将根据FormData对象生成适当的Content-Type。

但是,您将其替换为您手动创建的一个:

xhr.setRequestHeader('Content-type', 'multipart/form-data');

但是,缺少必需的boundary属性,因此PHP找不到用于拆分请求部分的点。

请勿覆盖内容类型。删除引号行。