Przesyłanie pliku bez formularza

96

Bez używania jakichkolwiek formularzy, mogę po prostu wysłać plik / pliki z <input type="file">do 'upload.php' używając metody POST używając jQuery. Znacznik input nie znajduje się w żadnym tagu formularza. Stoi indywidualnie. Dlatego nie chcę używać wtyczek jQuery, takich jak „ajaxForm” lub „ajaxSubmit”.

Elo Peri
źródło
1
Spróbuj tego: uploadify.com, ale użyj wersji flash. Chodź, rzuć kamieniem. Nie jestem pewien, czy wersja HTML5 działa bez formularza. Prawdopodobnie tak, ale nie jestem pewien.
Ismael Miguel
1
Arrr ... Chcę powiedzieć, że powinno działać w HTML 5. Ale będziesz pełen problemów ze zgodnością platform i przeglądarek starszych niż kilka lat. Jaka jest szkoda w tworzeniu formy lub dynamicznym generowaniu formy z podziemi?
Yitzhak

Odpowiedzi:

97

Możesz użyć FormData, aby przesłać swoje dane za pomocą żądania POST. Oto prosty przykład:

var myFormData = new FormData();
myFormData.append('pictureFile', pictureInput.files[0]);

$.ajax({
  url: 'upload.php',
  type: 'POST',
  processData: false, // important
  contentType: false, // important
  dataType : 'json',
  data: myFormData
});

Nie musisz używać formularza do wysyłania żądania Ajax, o ile znasz ustawienia żądania (takie jak adres URL, dane metody i parametrów).

Omid Monshizadeh
źródło
IMHO to najlepsze rozwiązanie, jednak innym wyborem jest użycie <iframe w środku, w którym możesz wysłać zwykły post z powrotem
John Smith
Tak to prawda. Starsze przeglądarki nie obsługują FormData i Ajax do przesyłania plików i rozwiązania, jeśli w tych przeglądarkach ma być używany element iframe jako zapasowy.
Omid Monshizadeh
7
Nie zapomnij dodać processData: falsei contentType: falsedo obiektu ustawień, inaczej otrzymasz Uncaught TypeError: Illegal invocation
jsmiff
2
Kolesie, uratowaliście mi życie !! : D Dziękuję @monshi i @ jsmiff. (SOF zabrania wielu użytkownikom w tym samym komentarzu).
Silvio Delgado
4
co to jest obraz?
developersaumya
32

Wszystkie odpowiedzi tutaj nadal korzystają z interfejsu API FormData . To jest jak "multipart/form-data"przesyłanie bez formularza. Możesz również przesłać plik bezpośrednio jako zawartość w treści POSTżądania, używając w xmlHttpRequestten sposób:

var xmlHttpRequest = new XMLHttpRequest();

var file = ...file handle...
var fileName = ...file name...
var target = ...target...
var mimeType = ...mime type...

xmlHttpRequest.open('POST', target, true);
xmlHttpRequest.setRequestHeader('Content-Type', mimeType);
xmlHttpRequest.setRequestHeader('Content-Disposition', 'attachment; filename="' + fileName + '"');
xmlHttpRequest.send(file);

Content-Typea Content-Dispositionnagłówki służą do wyjaśnienia, co wysyłamy (typ MIME i nazwa pliku).

Podobną odpowiedź zamieściłem również tutaj .

Więdnąć
źródło
1
To świetna odpowiedź. Całkowicie unika się używania danych formularza. Mogę dodać trochę więcej do użycia xmlHttpRequest. XMLHttpRequest pozwala na wykonywanie operacji asynchronicznych, które nie blokują klienta (strona UI). Podczas korzystania z formularza HTML klient (strona UI) jest blokowany podczas wykonywania operacji.
Harry
O co chodzi fetch()?
Witalij Zdanevich
@VitalyZdanevich nie wiesz, co masz na myśli?
Wilt
13

W oparciu o ten samouczek , oto bardzo podstawowy sposób, aby to zrobić:

$('your_trigger_element_selector').on('click', function(){    
    var data = new FormData();
    data.append('input_file_name', $('your_file_input_selector').prop('files')[0]);
    // append other variables to data if you want: data.append('field_name_x', field_value_x);

    $.ajax({
        type: 'POST',               
        processData: false, // important
        contentType: false, // important
        data: data,
        url: your_ajax_path,
        dataType : 'json',  
        // in PHP you can call and process file in the same way as if it was submitted from a form:
        // $_FILES['input_file_name']
        success: function(jsonData){
            ...
        }
        ...
    }); 
});

Nie zapomnij dodać odpowiedniej obsługi błędów

Zdumiewające
źródło
11

Krok 1: Utwórz stronę HTML, na której chcesz umieścić kod HTML.

Krok 2: Na dole strony kodowej HTML (stopka) Utwórz JavaScript: i umieść kod Jquery w tagu Script.

Krok 3: Utwórz plik PHP i skopiuj kod php w przeszłości. po Jquery Code in $.ajaxCode url zastosuj który z nich w nazwie pliku php.

JS

//$(document).on("change", "#avatar", function() {   // If you want to upload without a submit button 
$(document).on("click", "#upload", function() {
  var file_data = $("#avatar").prop("files")[0]; // Getting the properties of file from file field
  var form_data = new FormData(); // Creating object of FormData class
  form_data.append("file", file_data) // Appending parameter named file with properties of file_field to form_data
  form_data.append("user_id", 123) // Adding extra parameters to form_data
  $.ajax({
    url: "/upload_avatar", // Upload Script
    dataType: 'script',
    cache: false,
    contentType: false,
    processData: false,
    data: form_data, // Setting the data attribute of ajax with file_data
    type: 'post',
    success: function(data) {
      // Do something after Ajax completes 
    }
  });
});

HTML

<input id="avatar" type="file" name="avatar" />
<button id="upload" value="Upload" />

Php

print_r($_FILES);
print_r($_POST);
Hadiyal Rakesh
źródło
1
Dodaj komentarz / opis do swojego kodu
kvorobiev
brakuje ,potype: 'post'
Rust
1
Zrobiłem
czy możesz przesłać plik do tmpkatalogu do czasu przesłania całego formularza? (powiedz, że był to multi-form)?
thesayhey
Jak odniosę się do tych zmiennych formularza w kodzie java
Bhaskara Arani
1

Spróbuj tego prostego przesyłania , bez formularza

HTML:

<input type="file" name="arquivo" id="simpleUpload" multiple >
<button type="button" id="enviar">Enviar</button>

JavaScript:

$('#simpleUpload').simpleUpload({
  url: 'upload.php',
  trigger: '#enviar',
  success: function(data){
    alert('Envio com sucesso');

  }
});
Rodrigo Azevedo
źródło
1

Przepraszam, że jestem tym facetem, ale AngularJS oferuje proste i eleganckie rozwiązanie.

Oto kod, którego używam:

ngApp.controller('ngController', ['$upload',
function($upload) {

  $scope.Upload = function($files, index) {
    for (var i = 0; i < $files.length; i++) {
      var file = $files[i];
      $scope.upload = $upload.upload({
        file: file,
        url: '/File/Upload',
        data: {
          id: 1 //some data you want to send along with the file,
          name: 'ABC' //some data you want to send along with the file,
        },

      }).progress(function(evt) {

      }).success(function(data, status, headers, config) {
          alert('Upload done');
        }
      })
    .error(function(message) {
      alert('Upload failed');
    });
  }
};
}]);
.Hidden {
  display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div data-ng-controller="ngController">
  <input type="button" value="Browse" onclick="$(this).next().click();" />
  <input type="file" ng-file-select="Upload($files, 1)" class="Hidden" />
</div>

Po stronie serwera mam kontroler MVC z akcją, która zapisuje przesłane pliki znalezione w kolekcji Request.Files i zwraca JsonResult.

Jeśli używasz AngularJS, wypróbuj to, jeśli nie ... przepraszam kolego :-)

Shabi_669
źródło
Ocena negatywna, ponieważ nie działa z dyrektywą $ upload
NicoJuicy