Завантаження файлу без форми


94

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


1
Спробуйте це: uploadify.com, але використовуйте флеш-версію. Давай, кинь свій камінь. Я не впевнений, що версія HTML5 працює без форми. Можливо, буде, але я не впевнений.
Ісмаель Мігель

1
Arrr .... Я хочу сказати, що це повинно працювати в HTML 5. Але ви збираєтеся рятувати проблемами сумісності платформ у браузерах старше кількох років. Яка шкода при створенні форми або динамічному формуванні форми з пустель?
Іцхак

Відповіді:


94

Ви можете використовувати 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-адресу, дані методу та параметрів).


IMHO це найкраще рішення, однак іншим вибором є використання <iframe всередині, щоб ви могли зробити звичайний пост назад
Джон Сміт

Так, це правда. Старі браузери не підтримують FormData та ajax для завантаження файлів та рішення, якщо використовувати iframe як запасний варіант для цих браузерів.
Омід Моншізаде

7
Не забудьте додати processData: falseі contentType: falseв налаштуваннях об'єкту, інакше ви отримаєте неперехваченний TypeError: Illegal виклику
jsmiff

2
Чуваки, ви врятували мені життя !! : D Дякую @monshi та @ jsmiff. (SOF забороняє декількох користувачів в одному коментарі).
Сільвіо Дельгадо

4
що таке pictureInput у цьому ??
developersaumya

30

Всі відповіді тут все ще використовують 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 в$.ajax url коду застосуйте, який із них у вашому імені файлу 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
Будь ласка, додайте кілька коментарів / опис для вашого коду
kvorobiev

пропав ,післяtype: 'post'
Руст

1
Зробив мій день :) Дякую
shekhardtu

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

Як я буду посилатись на ці змінні форми у коді Java
Bhaskara Arani

1

Спробуйте цей пуглін 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, спробуйте це, якщо ні ... вибачте, товариш :-)


Проголосував проти, оскільки не працює з директивою $ upload
NicoJuicy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.