This is a pretty simple test before I implement some larger functionality. Eventually this will be just a glorified upload form via ajax.

Part 1 - Ajax post

    type: 'POST',        
    url: '/upload2',
    dataType: "json",
    data: JSON.stringify({"abc": "123", csrfTokenName: csrfTokenValue}),    
    success: function(data, textStatus){
        alert('form submitted successfully');            
    error: function (data, ErrorText, thrownError) {
        console.log("Failed to process request correctly, please try again");

Part 2 - Plugin

Plugin is installed. Inside my plugin init I've got a site rule setup:

$event->rules['upload2'] = 'plugin/default/upload';

I can visit this url in the browser without issue. Here's my function I'm trying to access:

public function actionUpload()
    $response_array['status'] = 'success';  
    $response_array['post'] = $_POST;
    return json_encode($response_array);

When I try and run said code via ajax, console returns Bad Request: Unable to verify your data submission. and a 400 (Bad Request) error to boot.

This could easily be one of those doh! moments but so far I'm losing this war. Should I just quit the internet and go live in the woods? (kidding)

Anyone have any idea what I'm doing wrong here? Are ajax posts different in Craft 3?

2 Answers 2


95% of the time you see a 400 Bad Request error, it's because it's a CSRF token validation error (or you're just missing the token all-together).

Craft 3 has CSRF validation enabled by default.

Here's how to pass the CSRF token to your JS in Craft 2: https://craftcms.com/support/csrf-protection#updating-your-javascript

Here's the CSRF token changes in Craft 3 you'll need to change: https://docs.craftcms.com/v3/changes-in-craft-3.html#csrf-token-params

  • The link for the CSRF changes for Craft 3 is broken. Feb 10, 2018 at 23:32
  • Yeah, link is still broken. I am looking for the same information today. Jun 13, 2018 at 10:37
  • Updated link...
    – Brad Bell
    Jun 13, 2018 at 19:13
  • @BradBell I'm building craft3 pwa app and issue with taken caching. Is there a way to check the token for each page load? Apr 9, 2020 at 10:20

For Craft3 in JS you can use var tokenInput = Craft.getCsrfInput(); to get the HTML input or Craft.csrfTokenName and Craft.csrfTokenValue for the Name and Value.

Then your post url should be
<form method="post" action="actions/plugin/default/ajax-call" accept-charset="UTF-8">

And finally in the controller

public function actionAjaxCall()
        $result = 'Welcome to the DefaultController actionAjaxCall() method';

        return $result;

That should be all you need

Your Answer

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

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