jQuery AJAX单文件上传

28

我知道这个问题已经被问了很多次,我尝试了至少10种不同的代码来运行它,但都没有成功。

我正在尝试使用jQuery.ajax()上传单个文件,但它不起作用。下面的代码总是输出:

请选择一个文件,因为文件名未设置或其他原因


HTML

<form enctype="multipart/form-data">
  <input name="file" type="file" />
  <input type="button" value="Upload" />
</form>
<div id="result"></div>

jQuery

$(function(){
  $(document).ready(function(){
    var files;

    $('input[type=file]').on('change', prepareUpload);
    function prepareUpload(event){
      files = event.target.files;
    };
    $(':button').click(function(){
        var formData = new FormData();
        $.each(files, function(key, value){
          formData.append(key, value);
        });
        alert(formData);
        $.ajax({
          url: 'check.php',  
          type: 'GET',
          data: formData,
          success: function(data){ $('#result').html(data); }, 
          cache: false,
          contentType: false,
          processData: false
        });
    });
  });
});

PHP

if(isset($_GET['file'])){
    $filename = $_FILES['file']['name'];
    if(isset($filename) && !empty($filename)){
        echo 'sup my man?!';
    }else{
        echo 'please choose a file';
    }
}else{
    echo 'not set';
}

我不知道问题出在哪里,我知道它在FormData对象创建中,因为警报-准备就绪无法正常工作。

顺便说一下,对我来说非常重要的是,它必须用jQuery编写。


1
你试过这个插件吗?(http://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax)我用过两三次,但它的效果非常好。 - CodeMonk
2
我使用plUpload插件。它似乎是比较流行的插件之一,而且对我来说运行良好。http://www.plupload.com/ - Johnny
谢谢大家,CodeMonk,是的我尝试过使用这个代码了,它与问题中的代码非常相似。还有Johnny,感谢你,但我正在尝试解决这个问题,我不想使用插件。 - user3195129
2个回答

31

经过几个小时的搜索和寻找答案,终于我做到了!!!! 下面是代码:))))

HTML:

<form id="fileinfo" enctype="multipart/form-data" method="post" name="fileinfo">
    <label>File to stash:</label>
    <input type="file" name="file" required />
</form>
<input type="button" value="Stash the file!"></input>
<div id="output"></div>

jQuery:

$(function(){
    $('#uploadBTN').on('click', function(){ 
        var fd = new FormData($("#fileinfo"));
        //fd.append("CustomField", "This is some extra data");
        $.ajax({
            url: 'upload.php',  
            type: 'POST',
            data: fd,
            success:function(data){
                $('#output').html(data);
            },
            cache: false,
            contentType: false,
            processData: false
        });
    });
});

upload.php 文件中,您可以访问使用 $_FILES['file'] 传递的数据。

感谢大家的帮助:)

我从这里获取了答案(稍作更改) MDN


7
改进:不要将完整的formdata传递给构造函数。使用 var formData = new FormData(); formData.append('file', $('input[type=file]')[0].files[0]); 数据: formData - tm1701
你需要使用tjm1706的改进才能使用这个解决方案。我已经尝试过有和没有这个改进。 - Michael Harley

14

A. 从文件字段中获取文件数据

第一步是将一个函数绑定到文件字段的更改事件上,以及一个用于抓取文件数据的函数:

// Variable to store your files
var files;

// Add events
$('input[type=file]').on('change', prepareUpload);

// Grab the files and set them to our variable
function prepareUpload(event)
{
  files = event.target.files;
}

此代码将文件数据保存到文件变量以备后用。

B. 在提交表单时处理文件上传

当表单被提交时,您需要在自己的 AJAX 请求中处理文件上传。添加以下绑定和功能:

$('form').on('submit', uploadFiles);

// Catch the form submit and upload the files
function uploadFiles(event)
{
  event.stopPropagation(); // Stop stuff happening
    event.preventDefault(); // Totally stop stuff happening

// START A LOADING SPINNER HERE

// Create a formdata object and add the files
var data = new FormData();
$.each(files, function(key, value)
{
    data.append(key, value);
});

$.ajax({
    url: 'submit.php?files',
    type: 'POST',
    data: data,
    cache: false,
    dataType: 'json',
    processData: false, // Don't process the files
    contentType: false, // Set content type to false as jQuery will tell the server its a query string request
    success: function(data, textStatus, jqXHR)
    {
        if(typeof data.error === 'undefined')
        {
            // Success so call function to process the form
            submitForm(event, data);
        }
        else
        {
            // Handle errors here
            console.log('ERRORS: ' + data.error);
        }
    },
    error: function(jqXHR, textStatus, errorThrown)
    {
        // Handle errors here
        console.log('ERRORS: ' + textStatus);
        // STOP LOADING SPINNER
    }
});
}

这个函数的作用是创建一个新的formData对象并将每个文件附加到它上面。然后将该数据作为请求发送到服务器。需要设置两个属性为false:
  • processData - 因为jQuery会将文件数组转换为字符串,而服务器无法接收。
  • contentType - 将其设置为false,因为jQuery默认为application/x-www-form-urlencoded,并且不发送文件。将其设置为multipart/form-data似乎也不起作用。

C.上传文件

快速而简单的php脚本来上传文件并返回一些信息:

<?php // You need to add server side validation and better error handling here

$data = array();

if(isset($_GET['files']))
{  
$error = false;
$files = array();

$uploaddir = './uploads/';
foreach($_FILES as $file)
{
    if(move_uploaded_file($file['tmp_name'], $uploaddir .basename($file['name'])))
    {
        $files[] = $uploaddir .$file['name'];
    }
    else
    {
        $error = true;
    }
}
$data = ($error) ? array('error' => 'There was an error uploading your files') : array('files' => $files);
}
else
{
    $data = array('success' => 'Form was submitted', 'formData' => $_POST);
}

echo json_encode($data);

?>

重要提示:不要使用此代码,请编写自己的代码。

D. 处理表单提交

上传函数的成功方法将从服务器返回的数据传递给 submit 函数。然后,您可以将其作为 post 的一部分传递到服务器:

function submitForm(event, data)
{
  // Create a jQuery object from the form
$form = $(event.target);

// Serialize the form data
var formData = $form.serialize();

// You should sterilise the file names
$.each(data.files, function(key, value)
{
    formData = formData + '&filenames[]=' + value;
});

$.ajax({
    url: 'submit.php',
    type: 'POST',
    data: formData,
    cache: false,
    dataType: 'json',
    success: function(data, textStatus, jqXHR)
    {
        if(typeof data.error === 'undefined')
        {
            // Success so call function to process the form
            console.log('SUCCESS: ' + data.success);
        }
        else
        {
            // Handle errors here
            console.log('ERRORS: ' + data.error);
        }
    },
    error: function(jqXHR, textStatus, errorThrown)
    {
        // Handle errors here
        console.log('ERRORS: ' + textStatus);
    },
    complete: function()
    {
        // STOP LOADING SPINNER
    }
});
}
最后备注

本脚本仅为示例,您需要处理服务器和客户端的验证,并找到一种通知用户文件上传正在进行的方法。如果您想查看它的工作原理,我在Github上创建了一个项目。

参考来源


谢谢你的再次帮助,但我已经尝试过了,没有成功。 - user3195129
你能展示一个演示/屏幕截图/任何内容来看看发生了什么吗? - CodeMonk
http://sell4you.co.il/study/ajaxFileUpload.html - user3195129
你将文件上传到哪里了?我看源代码并没有说太多。你的表单action在哪里? - CodeMonk
1
如果您在'$ .ajax'函数中指定了URL,则不应在表单选项卡中指定操作。 - user3195129

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接