web-dev-qa-db-fra.com

Admin Ajax et HTML5 Formdata

Lors de l'utilisation de FormData avec Wordpress Admin Ajax, je ne récupère qu'une réponse "0". Habituellement, c'est parce qu'il n'y a pas d'action, mais j'inclus l'action et j'ai toujours le problème. J'ai vu des questions similaires ici, mais ils supposent tous que jQuery est utilisé, et dans mon cas ce n'est pas le cas.

Javascript:

            if ($this.valid()) {

                var form_data = new FormData(form);
                form_data.append('security', WP.nonce);
                form_data.append('action', form.action);

                console.log(form.action); // console shows http://test.dev/newsletter_signup

                u.jax.post(WP.ajax, form_data, onSent);

                function onSent(result) {
                    if (result.success) {
                        $this.html('<p class="form-sent">' + $this.data('success') + '</p>');
                    } else {
                        $this.html('<p class="form-sent">' + result.data + '</p>');
                    }
                }
            }

PHP:

add_action('wp_ajax_newsletter_signup',         'newsletter_signup');
add_action('wp_ajax_nopriv_newsletter_signup',  'newsletter_signup');

HTML:

<form action="newsletter_signup" class="newsletter-signup js-process-form" autocomplete="off">
        <div class="field">
            <label for="newsletter-email" class="field__label">Your Email Address</label>
            <input type="email" class="field__input" name="email-address" id="newsletter-email" required data-msg-required="We need to know your email address" value="[email protected]">
            <button type="submit" class="field__button">submit</button>
        </div>

    </form>

Le seul problème que je peux voir est que l'action consiste à ajouter le domaine avant celui-ci. Si je fais cela avec jquery ajax, cela fonctionne très bien, donc le code semble descendre au javascript. Je peux fournir les fonctions ajax mais elles sont assez génériques.

Si vous avez besoin de plus de code, faites le moi savoir.

Merci.

Edit for comments:

J'ai essayé de remplacer le formulaire par le champ de saisie d'action masqué mentionné dans les commentaires:

<form action="">
        <input type="hidden" name="action" value="newsletter_signup"/>

        <div class="field">
            <label>Your Email Address</label>
            <input type="email" name="email-address">
            <button type="submit">submit</button>
        </div>

    </form>

Voici les données de formulaire envoyées lors de la soumission:

------WebKitFormBoundarycskAgc8KcinCzpoG
Content-Disposition: form-data; name:"action"

newsletter_signup
------WebKitFormBoundarycskAgc8KcinCzpoG
Content-Disposition: form-data; name="email-address"

[email protected]
------WebKitFormBoundarycskAgc8KcinCzpoG--

Et il est envoyé à:

http://test.dev/wp-admin/admin-ajax.php

Edit # 2:

Envoi d'une requête get comme:

u.jax.get('http://test.dev/wp-admin/admin-ajax.php?action=newsletter_si‌​gnup&email-address=t‌​[email protected]', function(s){
                console.log(s)
            });

Il en résulte également une réponse de 0.

Voici mes fonctions js ajax, en cas cela apporte une certaine clarté:

// ===== Ajax Utilities
// Handles Ajax Responses
function _handleResponse(request, success) {
    request.onreadystatechange = function() {
        if (request.status >= 200 && request.status < 400) {

            if (typeof request.responseText == 'string') {
                data = request.responseText;
            } else {
                data = JSON.parse(request.responseText);
            }

            success(data);

        } else {
            return request.status + ' failed request: '+ JSON.parse(request.responseText);
        }
    };

    request.onerror = function() {
        return request.status + ' failed request: '+ JSON.parse(request.responseText);
    };
}

// Ajax GET & POST
u.jax = {
    get: function(url, success) {
        var request = new XMLHttpRequest();

        request.open('GET', url, true);
        request.send(null);

        _handleResponse(request, success);

    },
    post: function(url, data, success) {
        var request = new XMLHttpRequest();

        request.open('POST', url, true);
        request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        request.send(data);

        _handleResponse(request, success);
    }
};

En-têtes de postier pour la demande d'obtention:

Cache-Control →no-cache, must-revalidate, max-age=0
Connection →Keep-Alive
Content-Length →1
Content-Type →text/html; charset=UTF-8
Date →Fri, 03 Mar 2017 16:16:54 GMT
Expires →Wed, 11 Jan 1984 05:00:00 GMT
Keep-Alive →timeout=5, max=100
Server →Apache/2.4.20 (Unix) PHP/5.5.35 mod_wsgi/3.5 Python/3.5.1 OpenSSL/1.0.1p
X-Content-Type-Options →nosniff
X-Frame-Options →SAMEORIGIN
X-Powered-By →PHP/5.5.35
X-Robots-Tag →noindex
1
evu

Le seul problème était donc le type de contenu de l'en-tête.

En supprimant request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); et en le laissant de côté, cela a bien fonctionné. C'est également avec l'action de formulaire qui est saisie et ajoutée.

Appel Ajax:

var formData = new FormData(form);
formData.append('security', WP.nonce);
formData.append('action', form.getAttribute('action'));

u.jax.post(WP.ajax, formData, onSent);

Fonction Ajax:

u.jax.post = function(url, data, success) {
    var request = new XMLHttpRequest();

    request.open('POST', url, true);
    request.send(data);

    request.onreadystatechange = function() {
        if (request.readyState === 4) {

            if (typeof request.responseText == 'string') {
                data = request.responseText;
            } else {
                data = JSON.parse(request.responseText);
            }

            success(data);
            return;

        }
    };
}

Forme:

<form action="newsletter_signup">

    <div class="field">
        <label>Your Email Address</label>
        <input type="email" name="email-address">
        <button type="submit">submit</button>
    </div>

</form>

PHP:

function newsletter_signup(){

    // Get the email address
    $email = sanitize_email($_POST['email-address']);

    // Do what you wish with the email address.

    //Setup the data to send back
    $data = array();

    // json encode the data to send back
    echo json_encode($data);
    exit;

}

add_action('wp_ajax_newsletter_signup',         'newsletter_signup');
add_action('wp_ajax_nopriv_newsletter_signup',  'newsletter_signup');
2
evu

FormData traite l'action de votre balise de formulaire en tant que partie des données de formulaire, lorsque ce n'est pas ce que vous souhaitez envoyer à admin-ajax.php. Essayez de trouver un autre moyen d'envoyer l'action 'newsletter_signup' à admin-ajax.php, principalement en construisant votre propre tableau:

var form_data = new FormData(form);
    form_data.append('security', WP.nonce);
    form_data.append('value', form.value);
    // etc. etc., for each value you want to send

var formData = {

    action: 'newsletter_signup',
    data: form_data

}

u.jax.post(WP.ajax, formData, onSent);

Aussi, qu'est-ce qui envoie le 0? Est-ce admin-ajax.php, ou est-ce une die() quelque part dans votre script php qui traite ces données de formulaire?

1
Spartacus