Viewed   232 times

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

 Answers

2

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);
Sunday, December 18, 2022
1

Here is how you can submit your form via Ajax:

function submitFormAjax() {
    let xmlhttp= window.XMLHttpRequest ?
        new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200)
            alert(this.responseText); // Here is the response
    }

    let name = document.getElementById('name').innerHTML;
    let email = document.getElementById('email').innerHTML;

    xmlhttp.open("GET","your_url.php?name=" + name + "&email=" + email, true);
    xmlhttp.send();
}

This example is using GET, but you could also use POST:

xmlhttp.open("POST","your_url.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("name=" + name + "&email=" + email);

Note:

You must call submitFormAjax() after validateFormOnSubmit is done with no errors, here:

if (reason.length == 0) {
    // Show some loading image and submit form
    submitFormAjax();
} else {
    return false;
}
Thursday, October 20, 2022
5

I have something very similar that I use:

<select name="selectProject" id="selectID" onChange="showUser(this.options[selectedIndex].value)">

    <?php
        // Loop through and list each project
        foreach ($var as $row) {
            echo '<option value="'.$row['projectNumber'].'">'.$row['projectName'].'</option>';
        }
    ?>

</select>

<label>Project Name</label>
<input id="projectName" type="text" class="span3" name="projectName">   

The above just calls the showUser function with the parameter that is the projectNumber

Then below that I have:

<SCRIPT TYPE="text/javascript">

    // Function to fill in form fields
    function showUser(str)
    {
    if (str=="")
      {
      document.getElementById("").innerHTML="";
      return;
      }
    if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            var obj = eval('(' + this.responseText + ')');


            document.getElementById("projectName").value=obj.projectname;
        }
      }
    xmlhttp.open("GET","http://url.com/ajax/"+str,true);
    xmlhttp.send();
    }
</SCRIPT>

This script will call the url url.com/ajax/whateverIdIsSelected

From that page, you want to do whatever you have to do with your query.

As for what to return, I have this set up to use json, which I why I have the line

 var obj = eval('(' + this.responseText + ')');

this.reponseText is what is returned from the ajax page. My return call looks like this

$projectData = json_encode($project);

echo $projectData;

Where $project is an array containing your project's attributes.

I'm not very good with ajax or js, but I got this working the way I like it. Let me know if you have questions

Sunday, August 28, 2022
 
5

That happens because jQuery converts the data you pass in to a string in the format of a form, with a application/x-www-form-urlencoded header, which is something PHP recognizes and correctly creates the $_POST superglobal from.

Your native XMLHttpRequest sends the data as a string in JSON format with the application/json header, which PHP does not recognize as form data, and does not create a $_POST array from.

In modern browsers you can use formData to create valid form data that can be sent with ajax and recognized by PHP

Wednesday, December 21, 2022
 
3

If you use XDebug, there is a maximum function nesting depth which is controlled by an ini setting:

$foo = function() use (&$foo) { 
    $foo();
};
$foo();

Produces the following error:

Fatal error: Maximum function nesting level of '100' reached, aborting!

This IMHO is a far better alternative than a segfault, since it only kills the current script, not the whole process.

There is this thread that was on the internals list a few years ago (2006). His comments are:

So far nobody had proposed a solution for endless loop problem that would satisfy these conditions:

  1. No false positives (i.e. good code always works)
  2. No slowdown for execution
  3. Works with any stack size

Thus, this problem remains unsloved.

Now, #1 is quite literally impossible to solve due to the halting problem. #2 is trivial if you keep a counter of stack depth (since you're just checking the incremented stack level on stack push).

Finally, #3 Is a much harder problem to solve. Considering that some operating systems will allocate stack space in a non-contiguous manner, it's not going to be possible to implement with 100% accuracy, since it's impossible to portably get the stack size or usage (for a specific platform it may be possible or even easy, but not in general).

Instead, PHP should take the hint from XDebug and other languages (Python, etc) and make a configurable nesting level (Python's is set to 1000 by default)....

Either that, or trap memory allocation errors on the stack to check for the segfault before it happens and convert that into a RecursionLimitException so that you may be able to recover....

Tuesday, November 15, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :