113

Without using any forms whatsoever, can I just send a file/files from <input type="file"> to 'upload.php' using POST method using jQuery. The input tag is not inside any form tag. It stands individually. So I don't want to use jQuery plugins like 'ajaxForm' or 'ajaxSubmit'.

Huangism
  • 15,899
  • 5
  • 47
  • 67
Elo Peri
  • 1,133
  • 2
  • 8
  • 6
  • 1
    Arrr.... I wantsta say it should work in HTML 5. But yera gonna to be rife with platform compatibility issues an' browsers of older than a few years. What be the harm in creating a form, or dynamically generatin a form from the nethers? – Yitzhak Sep 30 '15 at 04:12

7 Answers7

107

You can use FormData to submit your data by a POST request. Here is a simple example:

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

You don't have to use a form to make an ajax request, as long as you know your request setting (like url, method and parameters data).

AbdelHady
  • 8,576
  • 8
  • 53
  • 81
Omid Monshizadeh
  • 1,462
  • 1
  • 10
  • 12
42

All answers here are still using the FormData API. It is like a "multipart/form-data" upload without a form. You can also upload the file directly as content inside the body of the POST request using xmlHttpRequest like this:

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 and Content-Disposition headers are used for explaining what we are sending (mime-type and file name).

I posted similar answer also here.

Wilt
  • 37,062
  • 11
  • 138
  • 192
  • 1
    This is great answer. It is completely avoiding the usage of form data. I can add little more to the usage of xmlHttpRequest. An XMLHttpRequest allows for asynchronous operations to be performed, which don't block the client (UI page). While using an HTML form, the client(UI Page) is blocked while the operation is being performed. – Harry Mar 06 '19 at 17:04
  • 1
    What about `fetch()`? – Vitaly Zdanevich Apr 18 '20 at 00:23
  • 1
    @VitalyZdanevich not sure what you mean with that? – Wilt Apr 18 '20 at 07:19
  • @Harry, I am sure you are aware that AJAX, which most of the answers here use, also rely on xmlHttpRequest. And if you use FormData() instead of writing an actual form in HTML, you have no blocking. Cheers – Stephen Miller Jun 14 '21 at 07:51
17

Step 1: Create HTML Page where to place the HTML Code.

Step 2: In the HTML Code Page Bottom(footer)Create Javascript: and put Jquery Code in Script tag.

Step 3: Create PHP File and php code copy past. after Jquery Code in $.ajax Code url apply which one on your php file name.

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);
sijpkes
  • 169
  • 10
Hadiyal Rakesh
  • 231
  • 2
  • 7
14

Basing on this tutorial, here a very basic way to do that:

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

Don't forget to add proper error handling

Blaine_
  • 306
  • 3
  • 11
3

A non-jquery (React) version:

JS:

function fileInputUpload(e){

    let formData = new FormData();
    formData.append(e.target.name, e.target.files[0]);

    let response = await fetch('/api/upload', {
      method: 'POST',
      body: formData
    });

    let result = await response.json();

    console.log(result.message);
}

HTML/JSX:

<input type='file' name='fileInput' onChange={(e) => this.fileInput(e)} />

You might not want to use onChange, but you can attach the uploading part to any another function.

2

Try this puglin simpleUpload, no need form

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

  }
});
2

Sorry for being that guy but AngularJS offers a simple and elegant solution.

Here is the code I use:

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>

On the server side I have an MVC controller with an action the saves the files uploaded found in the Request.Files collection and returning a JsonResult.

If you use AngularJS try this out, if you don't... sorry mate :-)

Tim Penner
  • 3,513
  • 20
  • 35
Shabi_669
  • 190
  • 4