通过AJAX发送$ _FILES,输入多个

时间:2018-01-31 07:45:40

标签: jquery ajax

我尝试使用AJAX提交表单,其中包含两个变量和一个输入type="file"倍。 如果形式以clasic方式提交,则表格可以正常工作。 但是当我尝试使用AJAX时,$_FILES[]数组在.php侧出现空白。 我已经尝试过我所知道的一切,但是没有用。

以下是代码:

HTML

<form action="ajax/process.php" enctype="multipart/form-data" method="post" id="admUploadImg">
<input type="hidden" name="postOp" value="adm-upload-img">
<input type="hidden" name="pid" value="<?= $prodData['id'] ?>">
<div class="row my-2 mx-0 justify-content-center">
    <div class="col-12 col-sm-2 tb-1 text-left text-sm-right">Imagini 
        <label for="admProdImgs" class="btn btn-success btn-sm p-0 alert-success tip mb-1" title="Adauga imagini"><span class="icon-plus"></span></label>
        <input type="file" multiple id="admProdImgs" name="productImgs[]" class="filestyle invisible" data-form="admUploadImg" required accept="image/jpeg,image/png">
    </div>
</div>

的Javascript

$('#admUploadImg').submit(function(e){
    e.preventDefault();
    var formData = new FormData(this);
    $.post('ajax/process.php', formData, function(response){
        console.log(response);
    });
    console.log(formData);
});

但是,这会产生以下错误:

TypeError: 'append' called on an object that does not implement interface FormData.

所以,我已经将AJAX更改为:

$('#admUploadImg').submit(function(e){
    e.preventDefault();
    var formData = $('#admUploadImg').serialize();
    $.post('ajax/process.php', formData, function(response){
        console.log(response);
    });
    console.log(formData);
});

但这一次,$_FILES[]数组变空了。 它让我发疯,我不知道它为什么不起作用。救命啊!

2 个答案:

答案 0 :(得分:1)

此示例基于我使用的内容,它适用于我。我建议制作一个按钮或其他东西,因为它似乎不是用户可以用来提交表单的任何视觉元素(尽管这可能是故意的)。

&#13;
&#13;
<form enctype="multipart/form-data" id="admUploadImg" method="post">
    <input type="hidden" name="postOp" value="adm-upload-img" />
    <input type="hidden" name="pid" value="<?= $prodData['id'] ?>" />
    <div class="row my-2 mx-0 justify-content-center">
        <div class="col-12 col-sm-2 tb-1 text-left text-sm-right">Imagini 
            <label for="admProdImgs" class="btn btn-success btn-sm p-0 alert-success tip mb-1" title="Adauga imagini"><span class="icon-plus"></span></label>
            <input type="file" multiple id="admProdImgs" name="productImgs[]" class="filestyle invisible" data-form="admUploadImg" required accept="image/jpeg,image/png">
        </div>
        <button id="go">Upload</button>
    </div>
</form>
&#13;
&#13;
&#13;

由于您使用的是Ajax而不是使用传统HTML上传表单,因此您需要删除action="ajax/process.php"属性。这使得表单不以传统方式提交。这是JavaScript。

&#13;
&#13;
$("#go").click(function() {
    var f = $("#admUploadImg")[0];
    var form_data = new FormData(f);
    
    var file_data = $("#admProdImgs").prop("files");
    $.each(file_data, function(index, value) {
        form_data.append("productImgs", file_data[index]);
    });
    // unsure about this part, maybe try "productImgs[]" if the above doesn't work
    
    $.ajax({
        type: "post",
        url: "ajax/process.php",
        dataType: "text",
        contentType: false,
        processData: false,
        success: function (result) {
            console.log(result);
        }
    });
    console.log(form_data);
});
&#13;
&#13;
&#13;

我已将上述JavaScript更改为 .click() (按钮)的#go事件。我还切换到.ajax()来电,而不是.post()来电。你不会认为dataType: "text"会起作用,但这对我有用。我在自己的网站上使用的几乎是相同的东西,只有我的表单只需要3个单独的<input type="file" />元素。我尝试实现.each()来遍历用户可能选择的所有文件。

答案 1 :(得分:1)

由于关于formData()处理的另一个问题的评论,我已经成功解决了这个问题。

即使是onChange事件,也会发送表单中的所有内容。诀窍在于核心地处理formData,而且我错了。

使用此代码,我甚至不必从jQuery中查看$_FILES[]。我只是提交了表格。

我甚至成功地设置了一个实际可行的进度条。 :)

这是 Javascript代码

$('#admUploadImg').submit(function(e){
    e.preventDefault();
    showFadeProgress();
    var formData = new FormData(this);
    $.ajax({
        url : "ajax/process.php",
        xhr: function() {
            var xhr = $.ajaxSettings.xhr();
            xhr.upload.onprogress = function(e) {
                $('#admFilesUpload').css({width: Math.floor(e.loaded / e.total *100) + '%'});
            };
            return xhr;
        },
        type: "POST",
        data : formData,
        processData: false,
        contentType: false,
        success:function(response){
            $('#admProdImages').html(response);
            setTimeout(function(){
                restoreFadePopup();
            },100);
        }
    });
});

showFdeProgress()函数只显示带有消息和进度条的模态。

restoreFadePopup()函数在整个处理完成后关闭该模态。

对于#Tanner Babcock,不知道该说什么,我没有测试你的代码,我已经带来了这个解决方案,但我会回答你的答案。谢谢。