I have quite a simple registration form, something like this:

    <script type="text/javascript">
        window.csrfTokenName = "{{ craft.config.get('csrfTokenName') }}";
        window.csrfTokenValue = "{{ craft.request.getCsrfToken }}";
    </script>

    <form id="registerUser" method="post" accept-charset="UTF-8" class="flex-stack" novalidate @submit.prevent="userFormValidation()">
                        <input type="hidden" name="action" value="users/saveUser">
                        <input type="hidden" name="redirect" value="user/registration-success">

                        <label for="username">{{ "Username (no spaces)"|t }} <em>*</em></label>
                        <input id="username" type="text" name="username" v-model.lazy.trim="user.userDetails.userName" :class="{ 'error-field': usernameHasError }" required>
    </form>

It gets passed to VueJS (which works). There I have the default code I find in every AJAX post on Craft StackExchange:

var data = $('#registerUser').serializeArray();

            //--- Add CSRF token to data
            data[window.csrfTokenName] = window.csrfTokenValue;

            $.ajax({
                type: "POST",
                data: data,
                url: "",
                success: function(data, response){
                    console.log("success", response, data);
                },
                error: function(response) {
                    console.log("error", response);
                }
            });

This works when the CSRF is disabled in the config, but when enabled, I always get a bad request, CSRF token invalid error.

What am I doing wrong here? There's no Craft caching going on.

  • 1
    serializeArray won't produce data in a way Craft CMS will proceed it. It's not a good idea to do that. Besides that why don't you include the token in your form from the beginning? Because this is never the default code you can find in every ajax request – Robin Schambach Aug 23 at 17:06
  • But using the {{ getCsrfInput() }} in my form doesn't work with Ajax right? All I read on SE is by doing it the way I do it. But I can't add it to the data when I use serialize() instead. What does craft expect to get from a post Ajax to work with anyway? Any good examples I didn't find that you know of? – Tom De Smet Aug 23 at 21:48
  • Of course it works with ajax, why shouldn't it? You can't add it to the data because you are not supposed to do that. Just include the value to the form, serialize it and submit it – Robin Schambach Aug 23 at 21:50
  • Thanks man, it just works now. I don't know why all these other threads have the wrong answers. It's so simple... – Tom De Smet Aug 24 at 7:43
  • These answers are not wrong, you just used them wrong. Most other answers around here are about submitting custom data via ajax not about submitting serialized forms. So it's not their fault – Robin Schambach Aug 24 at 7:45
up vote 1 down vote accepted

Thanks to Robin Schambach. The answer was as simple as serialize the form data with the CSRF in there already by using the default {{ getCsrfInput() }}

serializeArray won't produce data in a way Craft CMS will proceed it. It's not a good idea to do that. Besides that why don't you include the token in your form from the beginning? Because this is never the default code you can find in every ajax request – Robin Schambach 14 hours ago

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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