Jquery/Ajax Form Submission (enctype="multipart/form-data" ). Why does 'contentType:False' cause undefined index in PHP?
Asked Answered
L

2

35

I have been trying to submit a form with enctype="multipart/form-data". I have this setting because the form will involve jpeg/png uploads once I have figured out the ajax submission for text inputs.

  1. the php works fine when referencing the script using action within the form html.

  2. the form data seems to be retrieved correctly by the below jquery because the alert line shows: productName=Test+Name&productDescription=Test+Description&OtherProductDetails=

  3. the returned data printed to my HTML by the jquery success function is a php error saying:Undefined index: productName

  4. removing contentType:false fixes the problem.

When i google jquery/ajax multipart/form-data submission, the top hits at least mainly include 'contentType:false'. Please could someone explain the reason to me?

http://digipiph.com/blog/submitting-multipartform-data-using-jquery-and-ajax http://hayageek.com/jquery-ajax-form-submit/ Sending multipart/formdata with jQuery.ajax

The jquery API documentation says: contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8') Type: String When sending data to the server, use this content type.

Why would we need to set it to false for a multipart/form-data submission? When would the false setting be needed at all?

Jquery:

  $("#addProductForm").submit(function (event) {
      event.preventDefault();
      //grab all form data  
      var formData = $(this).serialize();

      $.ajax({
          url: 'addProduct.php',
          type: 'POST',
          data: formData,
          async: false,
          cache: false,
          contentType: false,
          processData: false,
          success: function (returndata) {
              $("#productFormOutput").html(returndata);
              alert(formData);
          },
          error: function () {
              alert("error in ajax form submission");
          }
      });

      return false;
  });
Landgraviate answered 27/12, 2013 at 5:43 Comment(4)
Can you show me your form code here?Whitcher
it may be your form action attribute still set as 'addProduct.php' that is why jquery does not affect to form action.Whitcher
it was initially set to nothing. I changed it per the below answer which did not work.Landgraviate
Please check my updated answer formData sent via serialize() method.Whitcher
V
77

contentType option to false is used for multipart/form-data forms that pass files.

When one sets the contentType option to false, it forces jQuery not to add a Content-Type header, otherwise, the boundary string will be missing from it. Also, when submitting files via multipart/form-data, one must leave the processData flag set to false, otherwise, jQuery will try to convert your FormData into a string, which will fail.


To try and fix your issue:

Use jQuery's .serialize() method which creates a text string in standard URL-encoded notation.

You need to pass un-encoded data when using contentType: false.

Try using new FormData instead of .serialize():

  var formData = new FormData($(this)[0]);

See for yourself the difference of how your formData is passed to your php page by using console.log().

  var formData = new FormData($(this)[0]);
  console.log(formData);

  var formDataSerialized = $(this).serialize();
  console.log(formDataSerialized);
Valuation answered 31/12, 2013 at 21:0 Comment(1)
@ChaitanyaGadkari the workaround is to download a newer browser.Desperation
W
7

Please set your form action attribute as below it will solve your problem.

<form name="addProductForm" id="addProductForm" action="javascript:;" enctype="multipart/form-data" method="post" accept-charset="utf-8">

jQuery code:

$(document).ready(function () {
    $("#addProductForm").submit(function (event) {

        //disable the default form submission
        event.preventDefault();
        //grab all form data  
        var formData = $(this).serialize();

        $.ajax({
            url: 'addProduct.php',
            type: 'POST',
            data: formData,
            async: false,
            cache: false,
            contentType: false,
            processData: false,
            success: function () {
                alert('Form Submitted!');
            },
            error: function(){
                alert("error in ajax form submission");
            }
        });

        return false;
    });
});
Whitcher answered 27/12, 2013 at 5:51 Comment(6)
Thanks for the suggestion, i changed it to: <form id="addProductForm" action="javascript:;" enctype="multipart/form-data" method="post" accept-charset="utf-8">. No Change.Landgraviate
Thanks. The above serialise version is returning 'Form Submitted!'. Still nothing inserted to my DB though. It is my understanding that the last comment meant to use console.log as oppposed to alert.Landgraviate
@Pete please check your php script because jquery works fine as above code and yes console.log() as opposed to alert but it will work behind the script so your script will not stopped.Whitcher
Taking a look through the php; if it works with the standard form action submission, should it work with the serialise jquery? or will I have to make some kind of modifications to unserialise/handle the array of form data?Landgraviate
@Pete No need to change in php with serialse method. its same as php standard form submission.Whitcher
Still trying to figure this out. If I remove the jquery and use addProduct.php as the form action, the whole thing works. If I put in the jquery, and change the action to action="javascript:alert('Form action success!');", it does not. I get the 'Form Submitted!' Alert from the jquery but not the alert specified in the form action...Landgraviate

© 2022 - 2024 — McMap. All rights reserved.