0

I'm trying to upload a file and some text inside a textarea together using AJAX. I'm getting the following error in the PHP page that receives the data:

Notice: Undefined index: guion in file/path/here on line X

It means that the file is not being sent. Tried var_dump $_FILES and it output:

array(0) { }

HTML Code:

<div id="_AJAX_"></div>

<div role="form">
  <div id="fileGuionGroup" class="form-group">
    <label for="guion">Archivo Gui&oacute;n</label>
    <input id="fileGuion" type="file" name="guion">
  </div>

  <div id="txtComentarioGroup" class="form-group">
    <label for="comentario">Comentario</label>
    <textarea id="txtComentario" class="form-control" name="comentario" rows="4" placeholder="Ejemplo: Solicito que por favor se monte este curso en plataforma."></textarea>
  </div>
</div>

<button id="send_request" type="button" class="btn btn-primary btn-block" onclick="submitSolicitud(`{$cursoKey}`)"><i class="fa fa-fw fa-cogs"></i> Solicitar Montaje</button>

Javascript Code:

function submitSolicitud(cursoKey) {
  var fileGuion     = document.getElementById('fileGuion');
  var txtComentario = document.getElementById('txtComentario');

  var formGroupGuion      = document.getElementById('fileGuionGroup');
  var formGroupComentario = document.getElementById('txtComentarioGroup');

  formGroupGuion.className      = "form-group";
  formGroupComentario.className = "form-group";

  var guion      = fileGuion.value;
  var comentario = txtComentario.value;

  var formData = new FormData();
  formData.append('guion', guion);
  formData.append('comentario', comentario);

  connect = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

  connect.onreadystatechange = function () {
    onRSCallback(cursoKey);
  };

  connect.open('POST', '?view=modalsMatriz&modal=montaje&id=' + cursoKey + '&action=solicitarMontaje', true);
  connect.setRequestHeader("Content-Type", "multipart/form-data");
  connect.setRequestHeader("X-File-Name", guion.name);
  connect.setRequestHeader("X-File-Size", guion.size);
  connect.setRequestHeader("X-File-Type", guion.type);
  connect.send(formData);
};

PHP Code:

case 'solicitarMontaje':

    // This is the line that has the error of undefined index.
  die($_FILES['guion']);

  try {
    if (!isset($_FILES['guion'])) {
        # Code 1: Archivo Guión Field vacía
      throw new Exception(1);
    } elseif (!isset($_POST['comentario']) || $_POST['comentario'] == "") {
        # Code 2: Comentario Field vacío
      throw new Exception(2);
    }

    $tmp_file = $_FILES['guion']['tmp_name'];
    $filename = $_FILES['guion']['name'];

    move_uploaded_file($tmp_file, 'uploads/guiones/'.$filename);

    die(0);
    //$curso->crearSolicitudMontaje($_POST['comentario']);
  } catch (Exception $e) {
      # Output message to the screen so that Ajax captures it via connect.responseText @curso_FormMontaje.js
    echo $e->getMessage();
  }
break;  # ./ case 'solicitarMontaje'

I've tried it using FormData() and Content-Type multipart/form-data but it did not work at all. Instead it was making the page be embedded inside the _AJAX_ div that shows the messages returned from the server (such as success messages, errors at some fields i.e fields that were sent empty).

This is what I get as result using FormData when clicking the submit button:

https://postimg.org/image/rsnrt3yq9/

Rasclatt
  • 12,498
  • 3
  • 25
  • 33
  • 1
    Possible duplicate of [AJAX file upload/form submit without jquery or iframes?](http://stackoverflow.com/questions/11506510/ajax-file-upload-form-submit-without-jquery-or-iframes) – JD E Jul 25 '16 at 23:35
  • That code is not jQuery at all. It's pure Javascript. Aside from that I have a feeling that this code isn't written by you. It seems to be outdated code downloaded somewhere on the internet. I suggest you contact the programmer that wrote this to update his / her code, as aside from not functioning, it's very insecure as well. – icecub Jul 25 '16 at 23:47
  • 1
    For example: It wouldn't even stop me from uploading my own PHP (or other types of executable files) and pretty much do whatever I want with your server. Like deleting your website, replacing it with another website, deleting databases etc etc. – icecub Jul 25 '16 at 23:52
  • Hello icecub, thanks for replying. Yes I'm sorry that code is pure Javascript. The code is written by me, not downloaded from the internet. Also, I pasted the relevant parts of it here, not the whole code. Of course the file upload will have its restrinctions to close security breaches, but first I must be able to receive the file server-side, done that I can proceed with the tough security measurements. –  Jul 26 '16 at 04:10
  • You will want to revisit the `FormData()`, that is how you will get it working. – Rasclatt Jul 26 '16 at 04:10
  • Hello @Rasclatt, thanks for your reply. I've updated the post using `FormData()`, I'm having the expected error (please check the image at the end of the post). –  Jul 26 '16 at 15:27
  • @JuliánH Did you try out the example below? – Rasclatt Jul 26 '16 at 17:00

2 Answers2

0

Here is a very simple form data example, given what you have provided:

<script>
$(document).ready(function(){
    // I don't know what your form is called...
    $('.uploader').submit(function(e) {
        // Clone the file input
        var getFileInput    =   $("#fileGuion").clone();
        // Stop form from submitting
        e.preventDefault();
        $.ajax({
            url:'/url/to/ajax/dispatcher.php',
            // Use FormData object, pass form
            data: new FormData($(this)[0]),
            processData: false,
            contentType: false,
            type: 'post',
            success: function(response) {
                // Put html back into placeholder
                $('#_AJAX_').html(response);
                // Replace the input
                $("#fileGuion").replaceWith(getFileInput);
            }
        });
    });
});
</script>
<div id="_AJAX_"></div>
<form class="uploader">
    <label for="guion">Archivo Gui&oacute;n</label>
    <input id="fileGuion" type="file" name="guion">
    <label for="comentario">Comentario</label>
    <textarea id="txtComentario" class="form-control" name="comentario" rows="4" placeholder="Ejemplo: Solicito que por favor se monte este curso en plataforma."></textarea>
    <label>
        <input type="checkbox" id="ackCheckbox"> <i>He revisado y estoy seguro de continuar con esta acci&oacute;n.</i>
    </label>
    <input type="submit" value="Upload"> 
</form>
Rasclatt
  • 12,498
  • 3
  • 25
  • 33
  • It works! All the data is sent correctly. However; I tried your code after I already could figure out why mine was failing. Now reviewing your code I can see what makes both of our code work. I'm going to post what I did to solve the issue. Thanks for your help! –  Jul 30 '16 at 13:55
0

Turns out that what was causing issues were the HTTP headers (setRequestHeader). I removed them and edited the code a little bit, here's what it looks like now fully functional:

JavaScript Code:

function submitSolicitud(cursoKey) {
  var fileGuion     = document.getElementById('fileGuion');
  var txtComentario = document.getElementById('txtComentario');

  var guion      = fileGuion.files[0];
  var comentario = txtComentario.value;

  var formData = new FormData();

  formData.append('guion', guion);
  formData.append('comentario', comentario);

  connect = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

  connect.onreadystatechange = function () {
    onRSCallback(cursoKey);
  };

  connect.open('POST', '?view=modalsMatriz&modal=montaje&id=' + cursoKey + '&action=solicitarMontaje', true);

  connect.send(formData);
};       

As expected, the data is recognized by PHP as below:

  • The file "guion" comes into PHP's $_FILES array ($_FILES['guion']).

  • The "comentario" field (textarea) is sent inside PHP's $_POST array ($_POST['comentario']).

Finally, both HTML and PHP code stayed the same and the conclusion is that by not setting the HTTP headers they seem to take the proper value automatically so that the request processes correctly.