Tải lên tệp jQuery Ajax


755

Tôi có thể sử dụng mã jQuery sau đây để thực hiện tải lên tệp bằng phương thức POST của yêu cầu ajax không?

$.ajax({
    type: "POST",
    timeout: 50000,
    url: url,
    data: dataString,
    success: function (data) {
        alert('success');
        return false;
    }
});

Nếu có thể, tôi có cần điền datamột phần không? Đó có phải là cách chính xác? Tôi chỉ POST tập tin vào phía máy chủ.

Tôi đã đi vòng quanh, nhưng những gì tôi tìm thấy là một plugin trong khi trong kế hoạch của tôi, tôi không muốn sử dụng nó. Ít nhất là cho thời điểm này.


Ajax không hỗ trợ tải lên tệp, thay vào đó bạn nên sử dụng iframe
antyrat 23/210


Câu trả lời:


596

Không thể tải lên tệp thông qua AJAX.
Bạn có thể tải lên tập tin mà không cần làm mới trang bằng cách sử dụng IFrame.
Bạn có thể kiểm tra thêm chi tiết tại đây .


CẬP NHẬT

Với XHR2, tệp tải lên thông qua AJAX được hỗ trợ. Ví dụ thông qua FormDatađối tượng, nhưng tiếc là nó không được hỗ trợ bởi tất cả / các trình duyệt cũ.

FormData hỗ trợ bắt đầu từ các phiên bản trình duyệt máy tính để bàn.

  • IE 10+
  • Firefox 4.0+
  • Chrome 7+
  • Safari 5+
  • Opera 12+

Để biết thêm chi tiết, xem liên kết MDN .


41
Dưới đây là danh sách các trình duyệt cụ thể không được hỗ trợ: caniuse.com/#search=FormData Ngoài ra tôi chưa thử nghiệm điều này nhưng đây là một polyfill cho FormData gist.github.com/3120320
Ryan White

152
Cụ thể, IE <10 không, dành cho những người quá lười đọc liên kết.
Kevin

22
@Synexis không, chúng tôi không phải đợi lâu nữa vì tất cả IE chỉ có 22% thị phần trên toàn thế giới và 27% ở Mỹ và giảm nhanh. Rất có thể đó là những người trên 70 tuổi. Vì vậy, thay vào đó IE chỉ ra những gì các nhà phát triển phải làm IE sẽ phải hình thành hoặc thoát khỏi cuộc đua.
Drew Calder

30
@DrewCalder Hầu hết người dùng IE là nhân viên văn phòng không có lựa chọn sử dụng trình duyệt nào vì chính sách của công ty. Tôi không nghĩ tuổi tác có liên quan nhiều đến nó. Tôi đoán hầu hết mọi người> 70 có con cháu của họ để cài đặt Chrome hoặc FF thay thế :)
Nicolas Connault

3
Liên kết này thực sự giúp tôi hiểu được mức tối thiểu. Tôi đã không phải sử dụng một yêu cầu xhr. Nếu bạn làm sử dụng ajax chắc chắn để thiết lập enctypeđể "form/multipart"!
Sáng

316

Iframes không còn cần thiết để tải lên các tệp thông qua ajax. Gần đây tôi đã thực hiện nó một mình. Kiểm tra các trang sau:

Sử dụng tải lên tệp HTML5 với AJAX và jQuery

http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface

Cập nhật câu trả lời và làm sạch nó. Sử dụng hàm getSize để kiểm tra kích thước hoặc sử dụng hàm getType để kiểm tra các loại. Đã thêm mã tiến trình html và mã css.

var Upload = function (file) {
    this.file = file;
};

Upload.prototype.getType = function() {
    return this.file.type;
};
Upload.prototype.getSize = function() {
    return this.file.size;
};
Upload.prototype.getName = function() {
    return this.file.name;
};
Upload.prototype.doUpload = function () {
    var that = this;
    var formData = new FormData();

    // add assoc key values, this will be posts values
    formData.append("file", this.file, this.getName());
    formData.append("upload_file", true);

    $.ajax({
        type: "POST",
        url: "script",
        xhr: function () {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                myXhr.upload.addEventListener('progress', that.progressHandling, false);
            }
            return myXhr;
        },
        success: function (data) {
            // your callback here
        },
        error: function (error) {
            // handle error
        },
        async: true,
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        timeout: 60000
    });
};

Upload.prototype.progressHandling = function (event) {
    var percent = 0;
    var position = event.loaded || event.position;
    var total = event.total;
    var progress_bar_id = "#progress-wrp";
    if (event.lengthComputable) {
        percent = Math.ceil(position / total * 100);
    }
    // update progressbars classes so it fits your code
    $(progress_bar_id + " .progress-bar").css("width", +percent + "%");
    $(progress_bar_id + " .status").text(percent + "%");
};

Cách sử dụng lớp Tải lên

//Change id to your id
$("#ingredient_file").on("change", function (e) {
    var file = $(this)[0].files[0];
    var upload = new Upload(file);

    // maby check size or type here with upload.getSize() and upload.getType()

    // execute upload
    upload.doUpload();
});

Mã html thanh tiến trình

<div id="progress-wrp">
    <div class="progress-bar"></div>
    <div class="status">0%</div>
</div>

Mã tiến trình css

#progress-wrp {
  border: 1px solid #0099CC;
  padding: 1px;
  position: relative;
  height: 30px;
  border-radius: 3px;
  margin: 10px;
  text-align: left;
  background: #fff;
  box-shadow: inset 1px 3px 6px rgba(0, 0, 0, 0.12);
}

#progress-wrp .progress-bar {
  height: 100%;
  border-radius: 3px;
  background-color: #f39ac7;
  width: 0;
  box-shadow: inset 1px 1px 10px rgba(0, 0, 0, 0.11);
}

#progress-wrp .status {
  top: 3px;
  left: 50%;
  position: absolute;
  display: inline-block;
  color: #000000;
}

3
Bạn có thể ít nhiều sao chép mã ngay và sử dụng nó. Chỉ cần thay đổi một số tên id và tên lớp. Bất kỳ tùy chỉnh là của riêng bạn.
Ziinloader

4
Lưu ý rằng myXhr dường như là toàn cầu cũng như tên, kích thước và loại. Ngoài ra, tốt hơn là sử dụng "beforeSend" để tăng đối tượng XMLHttpRequest đã tạo hơn là sử dụng "xhr" để tạo một đối tượng sau đó thay đổi nó.
đánh thức

8
Tôi không nghĩ rằng chúng ta có thể sử dụng như @Ziinloader. Bạn đang sử dụng một số phương pháp cục bộ không bao gồm : writer(catchFile). Là writer()
tandrewnichols

4
Điều gì xảy ra nếu dữ liệu cũng chứa một vài trường cùng với tệp để tải lên?
raju

2
@Ziinloader Đây là một ví dụ cực kỳ hữu ích mà tôi thấy bạn đã quay lại và duy trì nhiều lần. Thực sự là một câu trả lời đáng giá hơn nhiều so với một câu trả lời tôi có thể đưa ra.
Joe thường xuyên

191

Có thể đăng bài và tải lên Ajax. Tôi đang sử dụng jQuery $.ajaxchức năng để tải các tập tin của tôi. Tôi đã cố gắng sử dụng đối tượng XHR nhưng không thể nhận được kết quả ở phía máy chủ với PHP.

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);

$.ajax({
       url : 'upload.php',
       type : 'POST',
       data : formData,
       processData: false,  // tell jQuery not to process the data
       contentType: false,  // tell jQuery not to set contentType
       success : function(data) {
           console.log(data);
           alert(data);
       }
});

Như bạn có thể thấy, bạn phải tạo một đối tượng FormData, trống hoặc từ (nối tiếp? - $('#yourForm').serialize())biểu mẫu hiện có, sau đó đính kèm tệp đầu vào.

Dưới đây là thông tin thêm: - Cách tải lên tệp bằng jQuery.ajax và FormData - Tải tệp lên qua jQuery, đối tượng FormData được cung cấp và không có tên tệp, yêu cầu GET

Đối với quy trình PHP, bạn có thể sử dụng một cái gì đó như thế này:

//print_r($_FILES);
$fileName = $_FILES['file']['name'];
$fileType = $_FILES['file']['type'];
$fileError = $_FILES['file']['error'];
$fileContent = file_get_contents($_FILES['file']['tmp_name']);

if($fileError == UPLOAD_ERR_OK){
   //Processes your file here
}else{
   switch($fileError){
     case UPLOAD_ERR_INI_SIZE:   
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_FORM_SIZE:  
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_PARTIAL:    
          $message = 'Error: no terminó la acción de subir el archivo.';
          break;
     case UPLOAD_ERR_NO_FILE:    
          $message = 'Error: ningún archivo fue subido.';
          break;
     case UPLOAD_ERR_NO_TMP_DIR: 
          $message = 'Error: servidor no configurado para carga de archivos.';
          break;
     case UPLOAD_ERR_CANT_WRITE: 
          $message= 'Error: posible falla al grabar el archivo.';
          break;
     case  UPLOAD_ERR_EXTENSION: 
          $message = 'Error: carga de archivo no completada.';
          break;
     default: $message = 'Error: carga de archivo no completada.';
              break;
    }
      echo json_encode(array(
               'error' => true,
               'message' => $message
            ));
}

2
Thư viện jquery nào tôi cần tham khảo để chạy mã này?
Rayden Black

Câu trả lời được viết vào năm 2014. Phiên bản của JQuery là 1.10. Tôi đã không thử với các phiên bản gần đây hơn.
pedrozopayares

5
formData.append('file', $('#file')[0].files[0]);trả lại undefinedconsole.log(formData) không có gì ngoại trừ_proto_
Yakob Ubaidi

1
Không được IE 9 hỗ trợ, trong trường hợp một số bị mắc kẹt trong cùng địa ngục với I
CountMurphy

3
Tôi đã làm việc này ... Ghim tôi, tôi đang tải lên tập tin jQuery Ajax! var formData = new FormData(); formData.append('file', document.getElementById('file').files[0]); $.ajax({ url : $("form[name='uploadPhoto']").attr("action"), type : 'POST', data : formData, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success : function(data) { console.log(data); alert(data); } });
TARKUS

104

Hình thức tải lên đơn giản

 <script>
   //form Submit
   $("form").submit(function(evt){	 
      evt.preventDefault();
      var formData = new FormData($(this)[0]);
   $.ajax({
       url: 'fileUpload',
       type: 'POST',
       data: formData,
       async: false,
       cache: false,
       contentType: false,
       enctype: 'multipart/form-data',
       processData: false,
       success: function (response) {
         alert(response);
       }
   });
   return false;
 });
</script>
<!--Upload Form-->
<form>
  <table>
    <tr>
      <td colspan="2">File Upload</td>
    </tr>
    <tr>
      <th>Select File </th>
      <td><input id="csv" name="csv" type="file" /></td>
    </tr>
    <tr>
      <td colspan="2">
        <input type="submit" value="submit"/> 
      </td>
    </tr>
  </table>
</form>


Thưa các js đã được sử dụng trong ví dụ này là gì, có một plugin jquery cụ thể cho cái này không..tôi có một câu hỏi tôi đã chỉ ra ở đây, bạn có thể kiểm tra câu hỏi của tôi không .. Tôi muốn tải lên nhiều tệp hoặc hình ảnh trong dự án đó tại đây là liên kết stackoverflow.com/questions/28644200/ Cách
Hồi sinh Brownman

19
$ (này) [0]đây
machineaddict

2
Tham số trên máy chủ cho tập tin được đăng là gì? Bạn có thể xin vui lòng gửi một phần máy chủ.
FrenkyB

@FrenkyB và những người khác - các tệp trên máy chủ (bằng PHP) không được lưu trữ trong biến $ _POST - chúng được lưu trữ trong biến $ _FILES. Trong trường hợp này, bạn sẽ truy cập nó với $ _FILES ["csv"] vì "csv" là thuộc tính tên của thẻ đầu vào.
dev_masta

68

Tôi khá muộn cho việc này nhưng tôi đang tìm kiếm một giải pháp tải lên hình ảnh dựa trên ajax và câu trả lời tôi đang tìm kiếm nằm rải rác trong bài đăng này. Giải pháp tôi đã giải quyết liên quan đến đối tượng FormData. Tôi lắp ráp một hình thức cơ bản của mã tôi đặt cùng nhau. Bạn có thể thấy nó trình bày cách thêm trường tùy chỉnh vào biểu mẫu với fd.append () cũng như cách xử lý dữ liệu phản hồi khi yêu cầu ajax được thực hiện.

Tải lên html:

<!DOCTYPE html>
<html>
<head>
    <title>Image Upload Form</title>
    <script src="//code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript">
        function submitForm() {
            console.log("submit event");
            var fd = new FormData(document.getElementById("fileinfo"));
            fd.append("label", "WEBUPLOAD");
            $.ajax({
              url: "upload.php",
              type: "POST",
              data: fd,
              processData: false,  // tell jQuery not to process the data
              contentType: false   // tell jQuery not to set contentType
            }).done(function( data ) {
                console.log("PHP Output:");
                console.log( data );
            });
            return false;
        }
    </script>
</head>

<body>
    <form method="post" id="fileinfo" name="fileinfo" onsubmit="return submitForm();">
        <label>Select a file:</label><br>
        <input type="file" name="file" required />
        <input type="submit" value="Upload" />
    </form>
    <div id="output"></div>
</body>
</html>

Trong trường hợp bạn đang làm việc với php, đây là một cách để xử lý việc tải lên bao gồm sử dụng cả hai trường tùy chỉnh được trình bày trong html ở trên.

Upload.php

<?php
if ($_POST["label"]) {
    $label = $_POST["label"];
}
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 200000)
&& in_array($extension, $allowedExts)) {
    if ($_FILES["file"]["error"] > 0) {
        echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    } else {
        $filename = $label.$_FILES["file"]["name"];
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";

        if (file_exists("uploads/" . $filename)) {
            echo $filename . " already exists. ";
        } else {
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "uploads/" . $filename);
            echo "Stored in: " . "uploads/" . $filename;
        }
    }
} else {
    echo "Invalid file";
}
?>

Tôi Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https,hiểu lý do tại sao vậy thưa ông, tôi sao chép dán mã của bạn như vậy
Brownman Revival 21/215

2
@HogRider - nếu bạn Google thông báo lỗi của bạn, đây là kết quả đầu tiên: stackoverflow.com/questions/10752055/ợi Bạn có đang truy cập các trang web của mình cục bộ thông qua file://, thay vì sử dụng máy chủ web không? Bên cạnh đó, không phải là cách tốt nhất để đơn giản là sao chép và dán mã một cách mù quáng mà không hiểu nó trước. Tôi khuyên bạn nên đi qua từng dòng mã để hiểu rõ về những gì đang xảy ra trước khi đưa mã vào sử dụng.
colincameron 18/03/2015

@colincameron cảm ơn bạn đã làm rõ một vài điều tôi đã làm qua từng dòng một và tôi không thực sự hiểu nhiều vì vậy tôi đã đặt câu hỏi để ai đó có thể làm rõ nghi ngờ của tôi. Tôi đang sử dụng local bằng cách xampp để chính xác. Tôi có thể hỏi một câu hỏi mà có lẽ bạn có thể làm rõ?
Hồi sinh Brownman

@Brownman Revival: Tôi biết rằng đã quá muộn để trả lời .. Bạn đã gặp lỗi xuất xứ chéo vì bạn đã mở tệp html dưới dạng tệp hơn là chạy nó từ máy chủ.
Adarsh ​​Mohan

@AdarshMohan tôi chấp nhận trả lời làm thế nào để bạn đề nghị tôi làm điều đó để làm cho đúng?
Hồi sinh Brownman

31

Một tải lên AJAX thực sự có thể với XMLHttpRequest(). Không có iframe cần thiết. Tiến trình tải lên có thể được hiển thị.

Để biết chi tiết, hãy xem: Trả lời https://stackoverflow.com/a/4943774/873282 để đặt câu hỏi Tiến trình tải lên jQuery và tải lên tệp AJAX .


24
Thật không may IE <10 không hỗ trợ này.
Sasha Chedygov

1
Khi bạn chỉ muốn đề cập đến một trang khác như một câu trả lời, bạn có thể bỏ phiếu để đóng dưới dạng dupkucate hoặc để lại nhận xét dưới câu hỏi. Bài đăng này không phải là một câu trả lời. Một bài đăng của loại này trông giống như một nỗ lực để đại diện trang trại.
mickmackusa

18

Đây là cách tôi làm việc này:

HTML

<input type="file" id="file">
<button id='process-file-button'>Process</button>

Mã não

$('#process-file-button').on('click', function (e) {
    let files = new FormData(), // you can consider this as 'data bag'
        url = 'yourUrl';

    files.append('fileName', $('#file')[0].files[0]); // append selected file to the bag named 'file'

    $.ajax({
        type: 'post',
        url: url,
        processData: false,
        contentType: false,
        data: files,
        success: function (response) {
            console.log(response);
        },
        error: function (err) {
            console.log(err);
        }
    });
});

PHP

if (isset($_FILES) && !empty($_FILES)) {
    $file = $_FILES['fileName'];
    $name = $file['name'];
    $path = $file['tmp_name'];


    // process your file

}

2
Điều giúp tôi nhiều nhất về điều này $('#file')[0].files[0]là một cách giải quyết kỳ lạ về JS mà không yêu cầu một cách phù hợp<form>
ffgpga08

Đây là giải pháp hoàn chỉnh, bit PHP cũng giúp.
cdsaenz

14

Trong trường hợp bạn muốn làm như vậy:

$.upload( form.action, new FormData( myForm))
.progress( function( progressEvent, upload) {
    if( progressEvent.lengthComputable) {
        var percent = Math.round( progressEvent.loaded * 100 / progressEvent.total) + '%';
        if( upload) {
            console.log( percent + ' uploaded');
        } else {
            console.log( percent + ' downloaded');
        }
    }
})
.done( function() {
    console.log( 'Finished upload');                    
});

hơn

https://github.com/lgersman/jquery.orangevolt-ampere/blob/master/src/jquery.upload.js

có thể là giải pháp của bạn


Phương thức tải lên ở đâu trong đối tượng $, liên kết trên không tồn tại
tuyệt vời nhất


2
Cảm ơn đã gửi câu trả lời của bạn! Hãy chắc chắn đọc Câu hỏi thường gặp về Tự quảng cáo một cách cẩn thận. Cũng lưu ý rằng nó là cần thiết mà bạn gửi một từ chối trách nhiệm mỗi khi bạn liên kết đến trang web / sản phẩm của riêng bạn.
Andrew Barber

13
  • Sử dụng iframe ẩn và đặt mục tiêu của biểu mẫu của bạn thành tên của iframe đó. Bằng cách này, khi biểu mẫu được gửi, chỉ iframe sẽ được làm mới.
  • Có một trình xử lý sự kiện đã đăng ký cho sự kiện tải của iframe để phân tích phản hồi.

Thêm chi tiết về bài đăng trên blog của tôi: http://blog.manki.in/2011/08/ajax-fie-upload.html .


Tránh iframe nếu có thể
Bhargav Nanekalva

@BhargavNanekalva mối quan tâm của bạn là gì?
aswzen

13
$("#submit_car").click( function() {
  var formData = new FormData($('#car_cost_form')[0]);
$.ajax({
       url: 'car_costs.php',
       data: formData,
       async: false,
       contentType: false,
       processData: false,
       cache: false,
       type: 'POST',
       success: function(data)
       {
       },
     })    return false;    
});

chỉnh sửa: Lưu ý loại nội dung và xử lý dữ liệu Bạn chỉ cần sử dụng tệp này để tải tệp lên qua Ajax ...... gửi đầu vào không thể nằm ngoài phần tử biểu mẫu :)


3
Sử dụng phương pháp này, bạn có thể đăng mẫu nhưng không phải với các trường loại 'tệp'. Câu hỏi này là cụ thể về tải lên tập tin.
Jomy John

11

Cập nhật 2019:

html

<form class="fr" method='POST' enctype="multipart/form-data"> {% csrf_token %}
<textarea name='text'>
<input name='example_image'>
<button type="submit">
</form>

js

$(document).on('submit', '.fr', function(){

    $.ajax({ 
        type: 'post', 
        url: url, <--- you insert proper URL path to call your views.py function here.
        enctype: 'multipart/form-data',
        processData: false,
        contentType: false,
        data: new FormData(this) ,
        success: function(data) {
             console.log(data);
        }
        });
        return false;

    });

lượt xem

form = ThisForm(request.POST, request.FILES)

if form.is_valid():
    text = form.cleaned_data.get("text")
    example_image = request.FILES['example_image']

1
Làm thế nào hạ điều này cải thiện bất kỳ câu trả lời đã được đưa ra? Ngoài ra, câu trả lời này có đề cập đến một tệp view.py là Django và không liên quan gì đến câu hỏi.
dirkgroten

6
Bởi vì vấn đề thể hiện tương đối giống nhau khi sử dụng Django và nếu bạn đang sử dụng Django, không có nhiều hướng ở đây liên quan đến việc giải quyết nó. Tôi nghĩ rằng tôi sẽ cung cấp hỗ trợ chủ động trong trường hợp có ai đến đây như tôi đã làm trong tương lai. Có một ngày khó khăn?
Jay

9

Sử dụng FormData. Nó hoạt động rất tốt :-) ...

var jform = new FormData();
jform.append('user',$('#user').val());
jform.append('image',$('#image').get(0).files[0]); // Here's the important bit

$.ajax({
    url: '/your-form-processing-page-url-here',
    type: 'POST',
    data: jform,
    dataType: 'json',
    mimeType: 'multipart/form-data', // this too
    contentType: false,
    cache: false,
    processData: false,
    success: function(data, status, jqXHR){
        alert('Hooray! All is well.');
        console.log(data);
        console.log(status);
        console.log(jqXHR);

    },
    error: function(jqXHR,status,error){
        // Hopefully we should never reach here
        console.log(jqXHR);
        console.log(status);
        console.log(error);
    }
});

đây là những gì: ('người dùng', $ ('# người dùng'). val ());
rahim.nagori

hộp văn bản với id = "người dùng" được thêm vào biểu mẫu @ rahim.nagori
Alp Altunel

Một cách tiếp cận trực tiếp hơn: var jform = new FormData ($ ('form'). Get (0));
André Morales

7

Tôi đã triển khai nhiều tệp chọn với xem trước và tải lên ngay lập tức sau khi xóa các tệp không mong muốn khỏi xem trước qua ajax.

Tài liệu chi tiết có thể được tìm thấy ở đây: http://anasthecoder.blogspot.ae/2014/12/multi-file-select-preview-without.html

Bản trình diễn: http://jsfiddle.net/anas/6v8Kz/7/embedded/result/

jsFiddle: http://jsfiddle.net/anas/6v8Kz/7/

Javascript:

    $(document).ready(function(){
    $('form').submit(function(ev){
        $('.overlay').show();
        $(window).scrollTop(0);
        return upload_images_selected(ev, ev.target);
    })
})
function add_new_file_uploader(addBtn) {
    var currentRow = $(addBtn).parent().parent();
    var newRow = $(currentRow).clone();
    $(newRow).find('.previewImage, .imagePreviewTable').hide();
    $(newRow).find('.removeButton').show();
    $(newRow).find('table.imagePreviewTable').find('tr').remove();
    $(newRow).find('input.multipleImageFileInput').val('');
    $(addBtn).parent().parent().parent().append(newRow);
}

function remove_file_uploader(removeBtn) {
    $(removeBtn).parent().parent().remove();
}

function show_image_preview(file_selector) {
    //files selected using current file selector
    var files = file_selector.files;
    //Container of image previews
    var imageContainer = $(file_selector).next('table.imagePreviewTable');
    //Number of images selected
    var number_of_images = files.length;
    //Build image preview row
    var imagePreviewRow = $('<tr class="imagePreviewRow_0"><td valign=top style="width: 510px;"></td>' +
        '<td valign=top><input type="button" value="X" title="Remove Image" class="removeImageButton" imageIndex="0" onclick="remove_selected_image(this)" /></td>' +
        '</tr> ');
    //Add image preview row
    $(imageContainer).html(imagePreviewRow);
    if (number_of_images > 1) {
        for (var i =1; i<number_of_images; i++) {
            /**
             *Generate class name of the respective image container appending index of selected images, 
             *sothat we can match images selected and the one which is previewed
             */
            var newImagePreviewRow = $(imagePreviewRow).clone().removeClass('imagePreviewRow_0').addClass('imagePreviewRow_'+i);
            $(newImagePreviewRow).find('input[type="button"]').attr('imageIndex', i);
            $(imageContainer).append(newImagePreviewRow);
        }
    }
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        /**
         * Allow only images
         */
        var imageType = /image.*/;
        if (!file.type.match(imageType)) {
          continue;
        }

        /**
         * Create an image dom object dynamically
         */
        var img = document.createElement("img");

        /**
         * Get preview area of the image
         */
        var preview = $(imageContainer).find('tr.imagePreviewRow_'+i).find('td:first');

        /**
         * Append preview of selected image to the corresponding container
         */
        preview.append(img); 

        /**
         * Set style of appended preview(Can be done via css also)
         */
        preview.find('img').addClass('previewImage').css({'max-width': '500px', 'max-height': '500px'});

        /**
         * Initialize file reader
         */
        var reader = new FileReader();
        /**
         * Onload event of file reader assign target image to the preview
         */
        reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
        /**
         * Initiate read
         */
        reader.readAsDataURL(file);
    }
    /**
     * Show preview
     */
    $(imageContainer).show();
}

function remove_selected_image(close_button)
{
    /**
     * Remove this image from preview
     */
    var imageIndex = $(close_button).attr('imageindex');
    $(close_button).parents('.imagePreviewRow_' + imageIndex).remove();
}

function upload_images_selected(event, formObj)
{
    event.preventDefault();
    //Get number of images
    var imageCount = $('.previewImage').length;
    //Get all multi select inputs
    var fileInputs = document.querySelectorAll('.multipleImageFileInput');
    //Url where the image is to be uploaded
    var url= "/upload-directory/";
    //Get number of inputs
    var number_of_inputs = $(fileInputs).length; 
    var inputCount = 0;

    //Iterate through each file selector input
    $(fileInputs).each(function(index, input){

        fileList = input.files;
        // Create a new FormData object.
        var formData = new FormData();
        //Extra parameters can be added to the form data object
        formData.append('bulk_upload', '1');
        formData.append('username', $('input[name="username"]').val());
        //Iterate throug each images selected by each file selector and find if the image is present in the preview
        for (var i = 0; i < fileList.length; i++) {
            if ($(input).next('.imagePreviewTable').find('.imagePreviewRow_'+i).length != 0) {
                var file = fileList[i];
                // Check the file type.
                if (!file.type.match('image.*')) {
                    continue;
                }
                // Add the file to the request.
                formData.append('image_uploader_multiple[' +(inputCount++)+ ']', file, file.name);
            }
        }
        // Set up the request.
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        xhr.onload = function () {
            if (xhr.status === 200) {
                var jsonResponse = JSON.parse(xhr.responseText);
                if (jsonResponse.status == 1) {
                    $(jsonResponse.file_info).each(function(){
                        //Iterate through response and find data corresponding to each file uploaded
                        var uploaded_file_name = this.original;
                        var saved_file_name = this.target;
                        var file_name_input = '<input type="hidden" class="image_name" name="image_names[]" value="' +saved_file_name+ '" />';
                        file_info_container.append(file_name_input);

                        imageCount--;
                    })
                    //Decrement count of inputs to find all images selected by all multi select are uploaded
                    number_of_inputs--;
                    if(number_of_inputs == 0) {
                        //All images selected by each file selector is uploaded
                        //Do necessary acteion post upload
                        $('.overlay').hide();
                    }
                } else {
                    if (typeof jsonResponse.error_field_name != 'undefined') {
                        //Do appropriate error action
                    } else {
                        alert(jsonResponse.message);
                    }
                    $('.overlay').hide();
                    event.preventDefault();
                    return false;
                }
            } else {
                /*alert('Something went wrong!');*/
                $('.overlay').hide();
                event.preventDefault();
            }
        };
        xhr.send(formData);
    })

    return false;
}

@Bhargav: Vui lòng xem bài đăng trên blog để được giải thích: goo.gl/umgFFy . Nếu bạn vẫn có bất kỳ câu hỏi nào, hãy liên hệ lại với tôi Cảm ơn
Ima

7

Tôi đã xử lý chúng trong một mã đơn giản. Bạn có thể tải về bản demo làm việc từ đây

Đối với trường hợp của bạn, những điều này rất có thể. Tôi sẽ hướng dẫn bạn từng bước làm thế nào bạn có thể tải tệp lên máy chủ bằng cách sử dụng AJAX jquery.

Trước tiên, chúng ta hãy tạo một tệp HTML để thêm phần tử tệp mẫu sau đây như được hiển thị bên dưới.

<form action="" id="formContent" method="post" enctype="multipart/form-data" >
         <input  type="file" name="file"  required id="upload">
         <button class="submitI" >Upload Image</button> 
</form>

Thứ hai tạo tệp jquery.js và thêm đoạn mã sau để xử lý việc gửi tệp của chúng tôi đến máy chủ

    $("#formContent").submit(function(e){
        e.preventDefault();

    var formdata = new FormData(this);

        $.ajax({
            url: "ajax_upload_image.php",
            type: "POST",
            data: formdata,
            mimeTypes:"multipart/form-data",
            contentType: false,
            cache: false,
            processData: false,
            success: function(){
                alert("file successfully submitted");
            },error: function(){
                alert("okey");
            }
         });
      });
    });

Có bạn xong rồi. Xem thêm


7

Sử dụng FormData là cách để đi như được chỉ ra bởi nhiều câu trả lời. đây là một chút mã hoạt động tuyệt vời cho mục đích này. Tôi cũng đồng ý với nhận xét về các khối ajax lồng nhau để hoàn thành các tình huống phức tạp. Bằng cách bao gồm e.PreventDefault (); theo kinh nghiệm của tôi làm cho mã tương thích nhiều trình duyệt hơn.

    $('#UploadB1').click(function(e){        
    e.preventDefault();

    if (!fileupload.valid()) {
        return false;            
    }

    var myformData = new FormData();        
    myformData.append('file', $('#uploadFile')[0].files[0]);

    $("#UpdateMessage5").html("Uploading file ....");
    $("#UpdateMessage5").css("background","url(../include/images/loaderIcon.gif) no-repeat right");

    myformData.append('mode', 'fileUpload');
    myformData.append('myid', $('#myid').val());
    myformData.append('type', $('#fileType').val());
    //formData.append('myfile', file, file.name); 

    $.ajax({
        url: 'include/fetch.php',
        method: 'post',
        processData: false,
        contentType: false,
        cache: false,
        data: myformData,
        enctype: 'multipart/form-data',
        success: function(response){
            $("#UpdateMessage5").html(response); //.delay(2000).hide(1); 
            $("#UpdateMessage5").css("background","");

            console.log("file successfully submitted");
        },error: function(){
            console.log("not okay");
        }
    });
});

điều này chạy biểu mẫu thông qua xác thực ... if (! fileupload.valid ()) {return false; }
Mike Volmar

7

Sử dụng js thuần sẽ dễ dàng hơn

async function saveFile(inp) 
{
    let formData = new FormData();           
    formData.append("file", inp.files[0]);
    await fetch('/upload/somedata', {method: "POST", body: formData});    
    alert('success');
}
<input type="file" onchange="saveFile(this)" >

  • Ở phía máy chủ, bạn có thể đọc tên tệp gốc (và thông tin khác) được tự động đưa vào yêu cầu.
  • Bạn KHÔNG cần đặt tiêu đề "Loại nội dung" thành trình duyệt "nhiều dữ liệu / biểu mẫu" sẽ tự động đặt nó
  • Giải pháp này sẽ hoạt động trên tất cả các trình duyệt chính.

Đây là đoạn mã phát triển hơn với xử lý lỗi và gửi json bổ sung


6

Có, bạn có thể, chỉ cần sử dụng javascript để lấy tệp, đảm bảo bạn đọc tệp dưới dạng URL dữ liệu. Phân tích nội dung trước cơ sở 64 để thực sự lấy dữ liệu được mã hóa cơ sở 64 và sau đó nếu bạn đang sử dụng php hoặc thực sự có bất kỳ ngôn ngữ phụ trợ nào, bạn có thể giải mã dữ liệu cơ sở 64 và lưu vào một tệp như dưới đây

Javascript:
var reader = new FileReader();
reader.onloadend = function ()
{
  dataToBeSent = reader.result.split("base64,")[1];
  $.post(url, {data:dataToBeSent});
}
reader.readAsDataURL(this.files[0]);


PHP:
    file_put_contents('my.pdf', base64_decode($_POST["data"]));

Tất nhiên bạn có thể sẽ muốn thực hiện một số xác nhận như kiểm tra loại tệp bạn đang xử lý và những thứ tương tự nhưng đây là ý tưởng.


file_put_contents ($ fname, file_get_contents ($ _ POST ['data'])); file_get_contents liên quan đến việc giải mã và dữ liệu: // tiêu đề
Nande

5
<html>
    <head>
        <title>Ajax file upload</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $(document).ready(function (e) {
            $("#uploadimage").on('submit', (function(e) {
            e.preventDefault();
                    $.ajax({
                    url: "upload.php", // Url to which the request is send
                            type: "POST", // Type of request to be send, called as method
                            data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
                            contentType: false, // The content type used when sending data to the server.
                            cache: false, // To unable request pages to be cached
                            processData:false, // To send DOMDocument or non processed data file it is set to false
                            success: function(data)   // A function to be called if request succeeds
                            {
                            alert(data);
                            }
                    });
            }));
        </script>
    </head>
    <body>
        <div class="main">
            <h1>Ajax Image Upload</h1><br/>
            <hr>
            <form id="uploadimage" action="" method="post" enctype="multipart/form-data">
                <div id="image_preview"><img id="previewing" src="noimage.png" /></div>
                <hr id="line">
                <div id="selectImage">
                    <label>Select Your Image</label><br/>
                    <input type="file" name="file" id="file" required />
                    <input type="submit" value="Upload" class="submit" />
                </div>
            </form>
        </div>
    </body>
</html>

4

Bạn có thể sử dụng phương pháp ajaxSubmit như sau :) khi bạn chọn một tệp cần tải lên máy chủ, hãy gửi mẫu tới máy chủ :)

$(document).ready(function () {
    var options = {
    target: '#output',   // target element(s) to be updated with server response
    timeout: 30000,
    error: function (jqXHR, textStatus) {
            $('#output').html('have any error');
            return false;
        }
    },
    success: afterSuccess,  // post-submit callback
    resetForm: true
            // reset the form after successful submit
};

$('#idOfInputFile').on('change', function () {
    $('#idOfForm').ajaxSubmit(options);
    // always return false to prevent standard browser submit and page navigation
    return false;
});
});

2
Tôi tin rằng bạn đang nói về plugin hình thức jquery . Nó thực sự là lựa chọn tốt nhất ở đây, ngoài việc thiếu chi tiết trong câu trả lời của bạn.
fotanus

@fotanus bạn nói đúng! tập lệnh đó phải sử dụng plugin biểu mẫu jquery để gửi phương thức sử dụng ajaxSubmit xác định trong plugin biểu mẫu jquery
Quy Le

4

để tải lên một tệp được gửi bởi người dùng như một phần của biểu mẫu bằng cách sử dụng jquery, vui lòng làm theo mã dưới đây:

var formData = new FormData();
formData.append("userfile", fileInputElement.files[0]);

Sau đó gửi đối tượng dữ liệu biểu mẫu đến máy chủ.

Chúng ta cũng có thể nối trực tiếp một tệp hoặc Blob vào đối tượng FormData.

data.append("myfile", myBlob, "filename.txt");

3

Nếu bạn muốn tải lên tệp bằng AJAX thì đây là mã mà bạn có thể sử dụng để tải tệp lên.

$(document).ready(function() {
    var options = { 
                beforeSubmit:  showRequest,
        success:       showResponse,
        dataType: 'json' 
        }; 
    $('body').delegate('#image','change', function(){
        $('#upload').ajaxForm(options).submit();        
    }); 
});     
function showRequest(formData, jqForm, options) { 
    $("#validation-errors").hide().empty();
    $("#output").css('display','none');
    return true; 
} 
function showResponse(response, statusText, xhr, $form)  { 
    if(response.success == false)
    {
        var arr = response.errors;
        $.each(arr, function(index, value)
        {
            if (value.length != 0)
            {
                $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>');
            }
        });
        $("#validation-errors").show();
    } else {
         $("#output").html("<img src='"+response.file+"' />");
         $("#output").css('display','block');
    }
}

Đây là HTML để tải tệp lên

<form class="form-horizontal" id="upload" enctype="multipart/form-data" method="post" action="upload/image'" autocomplete="off">
    <input type="file" name="image" id="image" /> 
</form>

3

Để có được tất cả các đầu vào biểu mẫu của bạn, bao gồm cả loại = "tệp", bạn cần sử dụng đối tượng FormData . bạn sẽ có thể thấy nội dung formData trong trình gỡ lỗi -> mạng -> Tiêu đề sau khi bạn sẽ gửi biểu mẫu.

var url = "YOUR_URL";

var form = $('#YOUR_FORM_ID')[0];
var formData = new FormData(form);


$.ajax(url, {
    method: 'post',
    processData: false,
    contentType: false,
    data: formData
}).done(function(data){
    if (data.success){ 
        alert("Files uploaded");
    } else {
        alert("Error while uploading the files");
    }
}).fail(function(data){
    console.log(data);
    alert("Error while uploading the files");
});

2
var dataform = new FormData($("#myform")[0]);
//console.log(dataform);
$.ajax({
    url: 'url',
    type: 'POST',
    data: dataform,
    async: false,
    success: function(res) {
        response data;
    },
    cache: false,
    contentType: false,
    processData: false
});

5
bạn có thể cải thiện câu trả lời của mình bằng cách thêm một số chi tiết
SR

1

Đây là một ý tưởng tôi đã nghĩ đến:

Have an iframe on page and have a referencer.

Có một hình thức trong đó bạn di chuyển phần tử INPUT: File sang.

Form:  A processing page AND a target of the FRAME.

Kết quả sẽ đăng lên khung, và sau đó bạn có thể gửi dữ liệu được tìm nạp lên một cấp độ cho thẻ hình ảnh bạn muốn với một cái gì đó như:

data:image/png;base64,asdfasdfasdfasdfa

và tải trang.

Tôi tin rằng nó hoạt động với tôi, và tùy thuộc vào bạn có thể làm một cái gì đó như:

.aftersubmit(function(){
    stopPropigation()// or some other code which would prevent a refresh.
});

Tôi không thấy cách này cải thiện bất kỳ câu trả lời nào khác được đưa ra trước đây. Ngoài ra, đó là Tuyên truyền không ủng hộ! ;)
JDuarteDJ
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.