1

When using FormData with Wordpress Admin Ajax I'm only getting back a '0' response. Usually this is because there's no action, however I'm including the action and still have the problem. I've seen similar questions on here but they all assume jQuery is being used, and in my case it isn't.

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>

The only problem I can see is that the action is getting the domain appended before it. If I do this with jquery ajax, it works fine, so the code seems down to the javascript. I can provide the ajax functions but they're pretty generic.

If there's any more code you need, let me know.

Thanks.

Edit for comments:

I have tried changing the form to the hidden action input field as mentioned in the comments:

<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>

This is the formdata sent on submit:

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

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

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

And it's being sent to:

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

Edit #2:

Sending a get request like:

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

Also results in a response of 0.

Here are my js ajax functions, incase it provides some clarity:

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

Postman Headers for the get request:

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
9
  • Don't use the action attribute of the form tag for the action, put it in a hidden input or a data attribute. They are unrelated things that happen to share a name.
    – Milo
    Mar 3, 2017 at 15:09
  • Removing the action from the form element and adding it as a hidden input instead has the same result unfortunately. As well as adding the action via the form_data.append('action', 'newsletter_signup'); method.
    – evu
    Mar 3, 2017 at 15:19
  • Have a look at this answer.
    – Milo
    Mar 3, 2017 at 15:24
  • Yep, saw that before posting. If I use that method it works. It's when not using jQuery I have problems, as I mentioned.
    – evu
    Mar 3, 2017 at 15:28
  • Assuming the Ajax URL is correct (wp-admin/admin-ajax.php), the action have to be submitted as a parameter action: wp_ajax_newsletter. So anything else than the correct action name will not work. As Milo said put your action in a hidden input or data attribute. I am guessing that is the problem . Check your post request in your browser console and see if everything is ok (ajax URL and POST params).
    – Laxmana
    Mar 3, 2017 at 15:29

2 Answers 2

2

So it turns out the only problem was the header content type.

By removing request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); and just leaving it out, it worked fine. That's also with the form action being grabbed and appended.

Ajax call:

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

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

Ajax Function:

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;

        }
    };
}

Form:

<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');
1

FormData is processing the action of your form tag as part of the form data, when that's not what you want to send to admin-ajax.php. Try to find another way to send 'newsletter_signup' as the action to admin-ajax.php, mainly by constructing your own array:

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

Also, what's sending the 0? Is it admin-ajax.php, or is it a die() somewhere in your php script that's processing this form data?

5
  • I never thought of trying this, I just have. I had to encode the data otherwise it would still return 0, (which I believe is from adminajax, as not an echo gets through). When encoded, however, it gets through but there is no $POST data, it's just [Object object]. How is jQuery ajax managing it?
    – evu
    Mar 6, 2017 at 8:49
  • When you say 'encoded', what do you mean? What are you using to encode? And you should be seeing all your form_data info as an array in $_POST['data']
    – Spartacus
    Mar 6, 2017 at 18:58
  • I meant url encoded, ie: action=newsletter_signup&email-address=". With the content type I had, $_POST['data'] just returned [object FormData].
    – evu
    Mar 7, 2017 at 8:44
  • Can you please post the PHP script that's receiving this ajax call?
    – Spartacus
    Mar 7, 2017 at 17:48
  • Sure, I've added it to the answer. But most of the stuff inside is controlled by lots of smaller functions so it's not that clear without those. I've added it's basic function though, so you can see how it accesses and returns the post data.
    – evu
    Mar 8, 2017 at 9:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.