如何使用jQuery序列化上传文件


81

所以我有一个表单,我正在使用jquery序列化功能通过ajax提交表单

        serialized = $(Forms).serialize();

        $.ajax({

        type        : "POST",
        cache   : false,
        url     : "blah",
        data        : serialized,
        success: function(data) {

        }

但是如果表单有一个<input type="file">字段怎么办...

Answers:


53

无法使用AJAX上传文件,因为您无法访问存储在客户端计算机上的文件内容,也无法使用javascript在请求中发送该文件。实现此目的的一种技术是使用隐藏的iframe。有一个不错的jquery表单插件,它允许您AJAXify表单,并且还支持文件上传。因此,使用此插件,您的代码将如下所示:

$(function() {
    $('#ifoftheform').ajaxForm(function(result) {
        alert('the form was successfully processed');
    });
});

插件会自动处理订阅submit表单事件,取消默认提交,序列化值,使用适当的方法并处理文件上载字段,...


42
这不再是事实。使用<input type ='file'name ='myfile'/>和FormData()对象,可以非常简单地使用AJAX保存文件。请参阅下面的Silver89的答案。
Rook777

1
@ Rook777,如果您使用的浏览器支持HTML5 File API,则当然是这样。您是否曾在IE中尝试过此操作,它有多简单?在HTML5成为标准并被所有浏览器支持之前,将出现插件,因为您无法使用AJAX上传文件。
Darin Dimitrov

2
你是对的。我很幸运能够处于不支持IE的开发环境中,所以我忘记了考虑它。是的,没有HTML5兼容性,此功能将无法使用。据caniuse.com/xhr2称到目前为止,仅IE 10+支持此功能。
Rook777

jQuery Form插件很棒!
user1570144

48

使用FormData对象,适用于任何形式的表格

$(document).on("submit", "form", function(event)
{
    event.preventDefault();
    $.ajax({
        url: $(this).attr("action"),
        type: $(this).attr("method"),
        dataType: "JSON",
        data: new FormData(this),
        processData: false,
        contentType: false,
        success: function (data, status)
        {

        },
        error: function (xhr, desc, err)
        {
            

        }
    });        

});

23
   var form = $('#job-request-form')[0];
        var formData = new FormData(form);
        event.preventDefault();
        $.ajax({
            url: "/send_resume/", // the endpoint
            type: "POST", // http method
            processData: false,
            contentType: false,
            data: formData,

它为我工作!只需将processData和contentType设置为False。


16

的HTML

<form name="my_form" id="my_form" accept-charset="multipart/form-data" onsubmit="return false">
    <input id="name" name="name" placeholder="Enter Name" type="text" value="">
    <textarea id="detail" name="detail" placeholder="Enter Detail"></textarea>
    <select name="gender" id="gender">
        <option value="male" selected="selected">Male</option>
        <option value="female">Female</option>
    </select>
    <input type="file" id="my_images" name="my_images" multiple="" accept="image/x-png,image/gif,image/jpeg"/>
</form>

的JavaScript

var data = new FormData();

//Form data
var form_data = $('#my_form').serializeArray();
$.each(form_data, function (key, input) {
    data.append(input.name, input.value);
});

//File data
var file_data = $('input[name="my_images"]')[0].files;
for (var i = 0; i < file_data.length; i++) {
    data.append("my_images[]", file_data[i]);
}

//Custom data
data.append('key', 'value');

$.ajax({
    url: "URL",
    method: "post",
    processData: false,
    contentType: false,
    data: data,
    success: function (data) {
        //success
    },
    error: function (e) {
        //error
    }
});

的PHP

<?php
    echo '<pre>';
    print_r($_POST);
    print_r($_FILES);
    echo '</pre>';
    die();
?>

如何发送提交按钮名称?
Muhammad Tarique

@MuhammadTarique您只需添加类似的按钮,<button type="button" name="button_name" value="Contact Button">Submit</button>然后在php端获得响应button_name =“ Contact Button”
Renish Patel

多谢您的回覆,但我认为这样行不通。但是,我已经通过使用formData.append("btnName", "true");
穆罕默德·塔里克

@MuhammadTarique这个例子已经在帖子中添加了data.append('key', 'value');
Renish Patel

11

您可以使用FormData方法通过AJAX上传文件。尽管IE7,8和9不支持FormData功能。

$.ajax({
    url: "ajax.php", 
    type: "POST",             
    data: new FormData('form'),
    contentType: false,       
    cache: false,             
    processData:false, 
    success: function(data) {
        $("#response").html(data);
    }
});

新FormData('form')中的'form'是什么,是否是id,对我不起作用
Mohamed Selim

是的,这通常是表单ID
Rossco

对我来说,它仅适用于document.forms.form而不是'form'字符串,传递给FormData构造函数
Mohamed Selim

10
$(document).on('click', '#submitBtn', function(e){
e.preventDefault();
e.stopImmediatePropagation();
var form = $("#myForm").closest("form");
var formData = new FormData(form[0]);
$.ajax({
    type: "POST",
    data: formData,
    dataType: "json",
    url: form.attr('action'),
    processData: false,
    contentType: false,
    success: function(data) {
         alert('Sucess! Form data posted with file type of input also!');
    }
)};});

通过使用new FormData()和设置processData: false, contentType:falseajax调用,使用文件输入形式提交表单对我有用

使用上面的代码,我也可以通过Ajax提交带有文件字段的表单数据


0

嗯,我认为有一种非常有效的方法可以专门针对希望定位所有浏览器的用户,而不仅仅是 支持FormData的浏览器

在页面上隐藏IFRAME并为From inside IFrame示例进行正常提交的想法

<FORM action='save_upload.php' method=post
   enctype='multipart/form-data' target=hidden_upload>
   <DIV><input
      type=file name='upload_scn' class=file_upload></DIV>
   <INPUT
      type=submit name=submit value=Upload /> <IFRAME id=hidden_upload
      name=hidden_upload src='' onLoad='uploadDone("hidden_upload")'
      style='width:0;height:0;border:0px solid #fff'></IFRAME> 
</FORM>

最重要的是使目标成为隐藏的iframe ID名称, 并编码multipart / form-data以允许接受照片

JavaScript端

function getFrameByName(name) {
    for (var i = 0; i < frames.length; i++)
        if (frames[i].name == name)
            return frames[i];

    return null;
}

function uploadDone(name) {
    var frame = getFrameByName(name);
    if (frame) {
        ret = frame.document.getElementsByTagName("body")[0].innerHTML;

        if (ret.length) {
            var json = JSON.parse(ret);
         // do what ever you want 
        }
    }
}

服务器端示例PHP

<?php
  $target_filepath = "/tmp/" . basename($_FILES['upload_scn']['name']);

  if (move_uploaded_file($_FILES['upload_scn']['tmp_name'], $target_filepath)) {
    $result = ....
  }

echo json_encode($result);
?>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.