6

I have a problem with my jQuery post request :

$.post(
  'http://localhost/***/ajax_bdd-change.php',
    {'id': _id, 'id_key': id_key, 'table': table, 'data': data})
    .fail(function(jqXHR, textStatus, errorThrown){
      alert('Erreur: '+jqXHR.responseText);
    })
    .done(function(data){
      alert($(data).text());
    });

And my PHP :

<?php
$id     = json_decode($_POST['id']);
$id_key = json_decode($_POST['id_key']);
$table  = json_decode($_POST['table']);
$data   = json_decode($_POST['data']);

foreach ($_POST as $k=>$v) {
  unset($_POST[$k]);
}
$rlt = array(
  'erreur' => false,
  'request' => 'none'
  ); 
$tmp = 0;
$request = 'UPDATE '.$table.' SET';

foreach ($data as $target => $value) {
  if ($tmp++>0)
    $request = $request.',';
  $request = $request.' '.$target.' = "'.$value.'"';
}
$request = $request.' WHERE '.$id_key.' LIKE "'.$id.'"';

$rlt['request'] = $request;

require('BDD_connexion.php');
if (!$rlt_bdd = mysqli_query($link, $request)){
  $rlt['erreur'] = 'Erreur: Update not done';
}
$link->close();

echo json_encode($rlt);
exit();

?>

Everytime I run my code, it follow the same path :

  • PHP is correctly executed
  • jQuery run .fail()
    • jqXHR.responseText is empty

I have try to force php to fail and at that time, the jQuery correctly run the done(function).

  • PHP have some error
  • jQuery run .done()
    • the alert show the php error

I have try many thing like force an UTF8 encode to each php string variable. I even try to impose a simple string like json_encode('hello world');

After many test, it seem my previous informations :

Maybe it is useful to explain that:

  • my javascript is inside a laod() php page.

So it must have a structure like:

  • main.php --jQuery-->load(second.php into a div)
    • second.php --jQuery-->$.post(ajax_bdd-change.php)
    • ajax_bdd-change.php --return $rlt -->second.php(jQuery part)

I do not mention it because I do not find it pertinent.

Is the cause of this problem. I have try a call of my php by post from a new html page without a .load and it is working perfectly.

Lolette
  • 71
  • 7
  • You want to check `textStatus` in your fail callback – Patrick Evans May 02 '16 at 13:45
  • I try to check the error because I do not understand why I always run the `fail()`function. I just try the`textStatus` it contain `error` – Lolette May 02 '16 at 14:08
  • I'd suggest not building a dynamic query directly with the $_POST variables unless you _explicitly_ define what values are allowed inside `id_key` and `table`, as well as actually using `mysqli` for what makes it valuable - data binding / prepared statements for SQL Injection prevention. That script is incredibly dangerous as-is. See here for binding: http://php.net/manual/en/mysqli-stmt.bind-param.php – Nate I May 02 '16 at 14:35
  • It seem your suggestion can have an influence...I find that everything work correctly but when I add `mysqli_query($link, $request)` it start to not bug. – Lolette May 02 '16 at 16:51
  • "Nate I" my `$_POST`are explecitly define and most of them are not given by the user but are data transmit directly by the code. – Lolette May 03 '16 at 08:53

4 Answers4

1

The response code, if nothing bad occurred on the server, should be 200.

It's highly likely, based off the observations you've made, that the response code is something other than 200. Also note, jQuery, or any other framework, doesn't know whether custom code, written on the server, was executed coherently. Usually, the only indication to the client is the response code.

jQuery source

Alex
  • 34,899
  • 5
  • 77
  • 90
  • Actually my status response code is `0` so it mean I do not have a response ? How can this be possible if the php is correctly executed ? (maybe it is not, but my database is correclty updated...and if I do another code after this one too is executed...) – Lolette May 02 '16 at 16:13
  • updated my answer with the source in jquery where the condition, based off the `responsecode`, is made. – Alex May 02 '16 at 16:20
  • sounds like, in PHP, you have to set the response header directly; in the fashion described in this post: http://stackoverflow.com/questions/3258634/php-how-to-send-http-response-code – Alex May 02 '16 at 17:08
  • I just try `http_response_code(200);` just before the `die(json_encode(...));` But that have no influance. It must be add in an other way ? – Lolette May 02 '16 at 17:19
  • check your configuration files, must be something external to the code you're actively working with... – Alex May 02 '16 at 17:20
  • it seem that is the `mysqli_query` that is generate this issue. Is it possible ? Can I try a substitue or manually remove this generation ? – Lolette May 03 '16 at 08:56
1

I have find a resolution. In fact, my code is more complex, and the jQuery .post is done in a .submit of a <form> inside the script part of an jQuery DialogBox. So the form was finished to submit before the php response when this on have a Database Query.

In resolution I change this submit with just a .click, and I manualy close when I recive a response from the server.

Lolette
  • 71
  • 7
0

First you have to decide that you want JSON in you AJAX Query like so:

    $.ajax({
        url:        'http://localhost/***/ajax_bdd-change.php',
        dataType:   'json',     //EXPLICITLY SET THIS TO JSON
        cache:      false,
        type:       "POST",
        data:       {
            id          : _id,
            id_key      : id_key,
            table       : table,
            data        : data
        },

        success: function (data, textStatus, jqXHR) {
            if(data){
                alert("DATA CAME BACK AS JSON...");
                console.log(data);
                // YOU REALLY DON'T WANT TO DO THIS: $(data).text() 
                // THE .text() METHOD IS FOR THE DOM AND YOU ARE IN READING MODE TOO
                // data SHOULD CONTAIN THESE: request AND erreur
                // SO YOU CAN EITHER CHECK THE SQL OR THE ERROR LIKE SO:
                // I WOULD PREFER USING console.log(data.request)
                alert(data.request);
                alert(data.erreur);
            }
        },

        error: function (jqXHR, textStatus, errorThrown) {
            alert('Erreur: '+jqXHR.responseText);
        },

        complete: function (jqXHR, textStatus) {
            //DO SOMETHING HERE IF YOU WISH TO
        } 
    });

And this is your PHP Code:

    <?php
        $id     = isset($_POST['id'])       ? htmlspecialchars(trim($_POST['id']))      : null;
        $id_key = isset($_POST['id_key'])   ? htmlspecialchars(trim($_POST['id_key']))  : null;
        $table  = isset($_POST['table'])    ? htmlspecialchars(trim($_POST['table']))   : null;
        $data   = isset($_POST['data'])     ? htmlspecialchars(trim($_POST['data']))    : null;


        foreach ($_POST as $k=>$v) {
            unset($_POST[$k]);
        }

        $rlt    = array(
            'erreur'    => false,
            'request'   => 'none'
        );

        $updateSQL  = 'UPDATE '. $table . ' SET ';
        if($data){
            foreach ($data as $target => $value) {
                $updateSQL .= ' ' . $target . ' = "' . $value . '", ';
            }
            $updateSQL  = rtrim($updateSQL, ", ");
            // LIKE CLAUSE IS NOT SO FUNKY HERE: DO YOU WANT TO DO "EQUALS"?
            // ' WHERE ' . $id_key . ' = "' . $id. '"';
            $condition  = ' WHERE ' . $id_key . ' LIKE "' . $id. '"';
            $request    = $updateSQL . $condition;

            $rlt['request'] = $request; 
            require('BDD_connexion.php');
            if (!$rlt_bdd = mysqli_query($link, $request)){
                $rlt['erreur'] = 'Erreur: Update not done';
            }
            $link->close();
        }

        die( json_encode($rlt) );

Hope this is a little close...

Poiz
  • 7,611
  • 2
  • 15
  • 17
  • I try your correction, but the same thing append: - PHP correctly executed - jQuery run `error()` and the `responseText` is empty – Lolette May 02 '16 at 14:48
0

Try this:

// Javascript

var params = {
    id: _id,
    id_key: id_key,
    table: table,
    data: data
};

// explicitely tells javascript you're expecting json response
// with this $.post shortcut

$.post('url', params, function(data) {
    //console.log(data)
    if (data.erreur) {
        // Error occured
    } else {
        // no error
    }
}, 'json');

// PHP

<?php

// You don't need to json_decode the $_POST data, but you can sanitize or
// perform any validation check if you want

$id = $_POST['id'];
$id_key = $_POST['id_key'];
$table = $_POST['table'];
$data = $_POST['data'];

// Your process here

echo json_encode($rlt);
exit;

Hope this helps.

maryus
  • 25
  • 4
  • Sorry, I miss te precise that all my variables are `JSON.stringify` before that – Lolette May 02 '16 at 15:02
  • I try your javascript and juste put a ` echo json_encode('ok'); exit();` but nothing append...it run in the `fail()` – Lolette May 02 '16 at 15:06
  • If you put only `echo json_encode('ok')` , it won't work because the javascript is expecting an object with the structure `{erreur: boolean, request: '...'}`. You can test with `echo json_encode(['erreur' => true]); exit; ` in your PHP. – maryus May 02 '16 at 15:20
  • I'm not sure I understand your issue. If your php contains only `echo json_encode(['erreur' => true]); exit;` the javascript should execute the `if (data.erreur) { ... }` section. Maybe you can post your full script (js and php) so we can better understand what's going on – maryus May 02 '16 at 15:39
  • Yes this is working with only `echo json_encode(['erreur' => true); exit;` – Lolette May 02 '16 at 15:48
  • So the error must come from my php side...thank you for this step in the resolution ;) – Lolette May 02 '16 at 15:52
  • I have try my code but I just switch the echo with the `echo json_encode(['erreur' => true]); exit;`from before, and it do not work anymore. So I must have something realy bad in it...I will make some trys – Lolette May 02 '16 at 15:54