cách tải tệp lên bằng cách sử dụng tuần tự hóa jquery


81

Vì vậy, tôi có một biểu mẫu và tôi đang gửi biểu mẫu thông qua ajax bằng cách sử dụng hàm tuần tự hóa jquery

        serialized = $(Forms).serialize();

        $.ajax({

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

        }

nhưng sau đó điều gì sẽ xảy ra nếu biểu mẫu có một <input type="file">trường .... làm cách nào để chuyển tệp vào biểu mẫu bằng phương pháp tuần tự hóa ajax này ... việc in $ _FILES không xuất ra bất kỳ thứ gì

Câu trả lời:


53

Không thể tải tệp lên bằng AJAX vì bạn không thể truy cập nội dung của tệp được lưu trữ trên máy khách và gửi tệp đó theo yêu cầu bằng javascript. Một trong những kỹ thuật để đạt được điều này là sử dụng iframe ẩn. Có một plugin biểu mẫu jquery đẹp mắt cho phép bạn AJAXify các biểu mẫu của mình và nó cũng hỗ trợ tải lên tệp . Vì vậy, bằng cách sử dụng plugin này, mã của bạn sẽ đơn giản như sau:

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

Plugin tự động xử lý việc đăng ký submitsự kiện của biểu mẫu, hủy gửi mặc định, tuần tự hóa các giá trị, sử dụng phương pháp thích hợp và xử lý các trường tải lên tệp, ...


42
Điều này không còn đúng nữa. Với <input type = 'file' name = 'myfile' /> và đối tượng FormData (), người ta có thể lưu một tệp bằng AJAX rất đơn giản. Xem câu trả lời của Silver89 bên dưới.
Rook777

1
@ Rook777, điều đó tất nhiên đúng nếu trình duyệt bạn đang sử dụng hỗ trợ API tệp HTML5. Bạn đã thử điều này trên IE xem nó đơn giản thế nào chưa? Cho đến khi HTML5 trở thành tiêu chuẩn và được hỗ trợ bởi tất cả các trình duyệt, sẽ có các plugin vì bạn không thể tải tệp lên bằng AJAX.
Darin Dimitrov

2
Bạn nói đúng. Tôi may mắn được ở trong một môi trường phát triển không hỗ trợ IE nên tôi đã quên xem xét nó. Có, nếu không có tính tương thích HTML5, tính năng này sẽ không hoạt động. Theo caniuse.com/xhr2 , cho đến nay chỉ có IE 10+ hỗ trợ tính năng này.
Rook777

jQuery Form Plugin thật tuyệt vời!
dùng1570144

48

Sử dụng FormDatađối tượng. Nó hoạt động cho mọi loại biểu mẫu

$(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,

Nó đã làm việc cho tôi! chỉ cần đặt processData và contentType Sai.


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();
?>

Làm thế nào để gửi tên nút gửi?
Muhammad Tarique

@MuhammadTarique Bạn chỉ cần thêm nút như <button type="button" name="button_name" value="Contact Button">Submit</button>và bạn sẽ có được câu trả lời BUTTON_NAME = "Liên Nút" ở bên cạnh php
Renish Patel

Cảm ơn bạn đã trả lời nhưng tôi không nghĩ rằng nó sẽ hoạt động theo cách này. Tuy nhiên tôi đã làm điều này bằng cách sử dụngformData.append("btnName", "true");
Muhammad Tarique

@MuhammadTarique Ví dụ này đã được thêm vào trong bài này giống nhưdata.append('key', 'value');
Renish Patel

11

Bạn có thể tải lên tệp qua AJAX bằng phương pháp FormData. Mặc dù IE7,8 và 9 không hỗ trợ chức năng FormData.

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

'hình thức' trong FormData mới ( 'form') là gì, nó là id, nó không làm việc cho tôi
Mohamed Selim

Có điều này sẽ thường là hình thức id
Rossco

với tôi nó chỉ làm việc với document.forms.form thay vì 'hình thức' chuỗi, truyền cho constructor 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!');
    }
)};});

Bằng cách sử dụng new FormData()và thiết lập processData: false, contentType:falsetrong cuộc gọi ajax gửi biểu mẫu với đầu vào tệp đã làm việc cho tôi

Sử dụng mã trên, tôi có thể gửi dữ liệu biểu mẫu với trường tệp cũng thông qua Ajax


0

hmmmm, tôi nghĩ có nhiều cách hiệu quả để làm cho nó đặc biệt cho những người muốn nhắm mục tiêu tất cả các trình duyệt chứ không chỉ FormData trình duyệt được hỗ trợ

ý tưởng ẩn IFRAME trên trang và gửi bình thường cho ví dụ Từ bên trong 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>

quan trọng nhất là tạo mục tiêu của biểu mẫu ID hoặc tên iframe ẩn và nhập dữ liệu đa phần / biểu mẫu để cho phép chấp nhận ảnh

bên 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 
        }
    }
}

Ví dụ về phía máy chủ 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);
?>

0

HTML5 giới thiệu FormData lớp có thể được sử dụng để tải tệp lên bằng ajax.

Hỗ trợ FormData bắt đầu từ các phiên bản trình duyệt máy tính để bàn sau đây. IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+

FormData - Mozilla.org

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.