我有一个问题发送文件到服务器端php脚本使用jQuery的ajax函数。 这是有可能得到文件列表与$('#fileinput').attr('文件'),但如何可能将此数据发送到服务器?当使用文件输入时,服务器端php-script上的结果数组($_POST)为0 (NULL)。

我知道这是可能的(尽管到目前为止我还没有找到任何jQuery解决方案,只有prototyye代码(http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html))。

这似乎是相对较新的,所以请不要提到文件上传将不可能通过XHR/Ajax,因为它肯定是工作的。

我需要的功能在Safari 5, FF和Chrome会很好,但不是必要的。

我现在的代码是:

$.ajax({
    url: 'php/upload.php',
    data: $('#file').attr('files'),
    cache: false,
    contentType: 'multipart/form-data',
    processData: false,
    type: 'POST',
    success: function(data){
        alert(data);
    }
});

当前回答

现在你甚至不需要jQuery:)获取API支持表

let result = fetch('url', {method: 'POST', body: new FormData(document.querySelector("#form"))})

其他回答

FormData类确实可以工作,但在iOS Safari(至少在iPhone上)我不能使用Raphael Schweikert的解决方案。

Mozilla Dev有一个关于操纵FormData对象的不错的页面。

因此,在页面的某个地方添加一个空表单,指定enctype:

<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo"></form>

然后,创建FormData对象如下:

var data = new FormData($("#fileinfo"));

就像拉斐尔的密码一样

只是想给拉斐尔的回答补充一点。下面是如何让PHP生成相同的$_FILES,而不管是否使用JavaScript提交。

HTML表单:

<form enctype="multipart/form-data" action="/test.php" 
method="post" class="putImages">
   <input name="media[]" type="file" multiple/>
   <input class="button" type="submit" alt="Upload" value="Upload" />
</form>

在没有JavaScript的情况下,PHP会生成这个$_FILES:

Array
(
    [media] => Array
        (
            [name] => Array
                (
                    [0] => Galata_Tower.jpg
                    [1] => 518f.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpIQaOYo
                    [1] => /tmp/phpJQaOYo
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 258004
                    [1] => 127884
                )

        )

)

如果你做渐进式增强,使用Raphael的JS提交文件…

var data = new FormData($('input[name^="media"]'));     
jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
    data.append(i, file);
});

$.ajax({
    type: ppiFormMethod,
    data: data,
    url: ppiFormActionURL,
    cache: false,
    contentType: false,
    processData: false,
    success: function(data){
        alert(data);
    }
});

... 这是PHP的$_FILES数组,使用JavaScript提交后的样子:

Array
(
    [0] => Array
        (
            [name] => Galata_Tower.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpAQaOYo
            [error] => 0
            [size] => 258004
        )

    [1] => Array
        (
            [name] => 518f.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpBQaOYo
            [error] => 0
            [size] => 127884
        )

)

这是一个很好的数组,实际上有些人将$_FILES转换为这个数组,但我发现使用相同的$_FILES是很有用的,不管是否使用JavaScript提交。所以,下面是对JS的一些小改动:

// match anything not a [ or ]
regexp = /^[^[\]]+/;
var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );

// make files available
var data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
    data.append(fileInputName+'['+i+']', file);
});

(2017年4月14日编辑:我从FormData()的构造函数中删除了form元素——在Safari中修复了这段代码。)

该代码做两件事。

自动检索输入名称属性,使HTML更易于维护。现在,只要表单有putImages类,其他一切都会自动处理。也就是说,输入不需要有任何特殊的名称。 普通HTML提交的数组格式由JavaScript在数据中重新创建。附加线。注意括号。

通过这些更改,使用JavaScript提交现在生成的$_FILES数组与使用简单HTML提交的数组完全相同。

旧版本的IE不支持FormData (FormData的完整浏览器支持列表在这里:https://developer.mozilla.org/en-US/docs/Web/API/FormData)。

你可以使用jquery插件(对于ex, http://malsup.com/jquery/form/#code-samples),或者,你可以使用基于IFrame的解决方案通过ajax发布多部分表单数据:https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript

如果文件输入名称指示一个数组并标记多个,并且使用FormData解析整个表单,则没有必要迭代地追加()输入文件。FormData将自动处理多个文件。

$('#submit_1').on('click', function() { let data = new FormData($("#my_form")[0]); $.ajax({ url: '/path/to/php_file', type: 'POST', data: data, processData: false, contentType: false, success: function(r) { console.log('success', r); }, error: function(r) { console.log('error', r); } }); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form id="my_form"> <input type="file" name="multi_img_file[]" id="multi_img_file" accept=".gif,.jpg,.jpeg,.png,.svg" multiple="multiple" /> <button type="button" name="submit_1" id="submit_1">Not type='submit'</button> </form>

注意,这里使用的是常规按钮type="button",而不是type="submit"。这表明不依赖于使用submit来获得此功能。

结果$_FILES条目在Chrome开发工具中是这样的:

multi_img_file:
  error: (2) [0, 0]
  name: (2) ["pic1.jpg", "pic2.jpg"]
  size: (2) [1978036, 2446180]
  tmp_name: (2) ["/tmp/phphnrdPz", "/tmp/phpBrGSZN"]
  type: (2) ["image/jpeg", "image/jpeg"]

注意:在某些情况下,某些图像在作为单个文件上传时可以正常上传,但在以一组多个文件上传时就会失败。其症状是PHP报告空$_POST和$_FILES,而AJAX没有抛出任何错误。问题发生在Chrome 75.0.3770.100和PHP 7.0。在我的测试集中,几十张图片中似乎只有一张出现这种情况。

如果表单是在HTML中定义的,那么将表单传递给构造函数要比迭代和添加图像容易得多。

$('#my-form').submit( function(e) {
    e.preventDefault();

    var data = new FormData(this); // <-- 'this' is your form element

    $.ajax({
            url: '/my_URL/',
            data: data,
            cache: false,
            contentType: false,
            processData: false,
            type: 'POST',     
            success: function(data){
            ...