Загрузка файла без формы


96

Могу ли я просто отправить файл / файлы из файла <input type="file">'upload.php' без использования каких-либо форм с помощью метода POST с использованием jQuery. Тег ввода не находится внутри тега формы. Стоит индивидуально. Поэтому я не хочу использовать плагины jQuery, такие как ajaxForm или ajaxSubmit.


1
Попробуйте это: uploadify.com, но используйте флэш-версию. Давай, брось свой камень. Я не уверен, что версия HTML5 работает без формы. Возможно, будет, но я не уверен.
Исмаэль Мигель

1
Arrr .... Я хочу сказать, что он должен работать в HTML 5. Но вы будете изобиловать проблемами совместимости платформ и браузерами старше нескольких лет. Какой будет вред в создании формы или динамическом создании формы из преисподней?
Ицхак

Ответы:


97

Вы можете использовать FormData для отправки данных с помощью запроса POST. Вот простой пример:

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
});

Вам не нужно использовать форму для выполнения запроса ajax, если вы знаете настройки своего запроса (например, URL-адрес, метод и данные параметров).


ИМХО, это лучшее решение, однако другой вариант - использовать <iframe внутри, вы можете делать обычный пост обратно
Джон Смит

Да, это правда. Старые браузеры не поддерживают FormData и ajax для загрузки файлов и решения, если использовать iframe в качестве запасного варианта для этих браузеров.
Омид Моншизаде

7
Не забудьте добавить processData: falseи contentType: falseк объекту настроек, иначе вы получите
Uncaught TypeError

2
Мужики, вы спасли мне жизнь !! : D Спасибо @monshi и @ jsmiff. (SOF запрещает использование нескольких пользователей в одном комментарии).
Сильвио Дельгадо,

4
что такое pictureInput в этом ??
developersaumya

34

Все ответы здесь все еще используют API FormData . Это похоже на "multipart/form-data"загрузку без формы. Вы также можете загрузить файл непосредственно как содержимое внутри тела POSTзапроса, используя xmlHttpRequestследующее:

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-Typeа Content-Dispositionзаголовки используются для объяснения того, что мы отправляем (тип mime и имя файла).

Я также разместил аналогичный ответ здесь .


1
Это отличный ответ. Это полностью исключает использование данных формы. Я могу добавить немного больше к использованию xmlHttpRequest. XMLHttpRequest позволяет выполнять асинхронные операции, которые не блокируют клиента (страницу пользовательского интерфейса). При использовании HTML-формы клиент (страница пользовательского интерфейса) блокируется на время выполнения операции.
Гарри

О чем fetch()?
Виталий Зданевич

@VitalyZdanevich не уверен, что вы имеете в виду?
Уилт

13

Основываясь на этом руководстве , вот очень простой способ сделать это:

$('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){
            ...
        }
        ...
    }); 
});

Не забудьте добавить правильную обработку ошибок


11

Шаг 1: Создайте HTML-страницу, на которой нужно разместить HTML-код.

Шаг 2: В нижней части страницы кода HTML (нижний колонтитул) создайте Javascript: и поместите код Jquery в тег Script.

Шаг 3: Создайте файл PHP и скопируйте код PHP. после кода JQuery в $.ajaxURL- адресе кода применяется тот, который указан в имени вашего файла 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);

1
Пожалуйста, добавьте комментарии / описание к вашему коду
Кворобиев

отсутствует ,послеtype: 'post'
GoalsAndGambles 05

1
Сделал свой день :) Спасибо
shekhardtu

вы можете загрузить файл в tmpкаталог, пока не будет отправлена ​​вся форма? (скажем, это была мультиформа)?
thesayhey

Как я буду ссылаться на эти переменные формы в java-коде
Бхаскара Арани

1

Попробуйте этот puglin simpleUpload , без формы

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');

  }
});

1

Извините за то, что был таким парнем, но AngularJS предлагает простое и элегантное решение.

Вот код, который я использую:

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>

На стороне сервера у меня есть контроллер MVC с действием, которое сохраняет загруженные файлы, найденные в коллекции Request.Files, и возвращает JsonResult.

Если вы используете AngularJS, попробуйте это, если нет ... извините, приятель :-)


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.