【问题标题】:XMLHttpRequest() not sending FormData() resulting in empty PHP $_FILES array and no file uploadedXMLHttpRequest() 不发送 FormData() 导致空 PHP $_FILES 数组并且没有上传文件
【发布时间】:2019-07-22 08:33:47
【问题描述】:

我想要做什么:

基本上,我正在尝试将文件上传到用户通过 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(上传.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() 对象和 &lt;input&gt; 更改事件通过添加提交按钮来提交表单,尽管页面重定向到 ...url/upload.php 并且没有异步工作,$_FILES 数组包含上传文件的正确数据,并且文件已上传到服务器,这让我认为我的 Javascript 代码中一定存在问题,与 XMLHttpRequest 或 @987654336 有关@对象。

【问题讨论】:

  • 这个问题是在IE 还是在任何其他浏览器中?
  • 你能在没有 setRequestHeader 行的情况下试试这个吗? developer.mozilla.org/en-US/docs/Web/API/FormData/… 下的示例也无需手动指定 Content-Type。
  • @AndreiLupuleasa 我正在使用 Chrome,但我假设每个浏览器
  • @04FS 哇,这样就修复了它...我遇到的每个示例都明确指出该行是必要的,但删除它可以使其工作...很奇怪,但非常感谢!随意写下来作为答案,我会接受,如果没有,我可以为你写答案:)
  • 然后你应该在开发工具中查看你的文件是否真的被发送了。

标签: javascript php forms xmlhttprequest asyncfileupload


【解决方案1】:

通常,XMLHttpRequest 会从 FormData 对象生成适当的 Content-Type。

但是,您正在使用手动创建的内容覆盖它:

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

但是,强制的boundary 属性缺失,所以PHP 找不到分割请求部分的点。

不要覆盖 Content-Type。删除引用的行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-04
    • 2013-11-10
    • 2015-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多