<p>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).</p>

<p>Craft 3 has CSRF validation enabled by default.</p>

<p>Here's how to pass the CSRF token to your JS in Craft 2: <a href="https://craftcms.com/support/csrf-protection#updating-your-javascript" rel="nofollow noreferrer">https://craftcms.com/support/csrf-protection#updating-your-javascript</a></p>

<p>Here's the CSRF token changes in Craft 3 you'll need to change: <a href="https://docs.craftcms.com/v3/changes-in-craft-3.html#csrf-token-params" rel="nofollow noreferrer">https://docs.craftcms.com/v3/changes-in-craft-3.html#csrf-token-params</a></p>

CC BY-SA 3.0
2018-02-10T23:32:57.077Z
The link for the CSRF changes for Craft 3 is broken.
Mark Notton
CC BY-SA 4.0
2018-06-13T10:37:15.663Z
Yeah, link is still broken. I am looking for the same information today.
Dan Zuzevich
CC BY-SA 4.0
2018-06-13T19:13:04.523Z
Updated link...
Brad Bell
CC BY-SA 4.0
2020-04-09T10:20:29.613Z
@BradBell I'm building craft3 pwa app and issue with taken caching. Is there a way to check the token for each page load?
Sameera Thilakasiri
CC BY-SA 4.0
2017-11-19T01:05:29.847Z
2018-06-13T19:12:50.203Z
2018-06-13T19:12:50.203Z
Brad Bell
<p>For Craft3 in JS you can use <code>var tokenInput = Craft.getCsrfInput();</code> to get the HTML input or <code>Craft.csrfTokenName</code> and <code>Craft.csrfTokenValue</code> for the Name and Value. </p>

<p>Then your post url should be<br>
<code>&lt;form method="post" action="actions/plugin/default/ajax-call" accept-charset="UTF-8"&gt;</code></p>

<p>And finally in the controller</p>

<pre><code>public function actionAjaxCall()
     {
        $result = 'Welcome to the DefaultController actionAjaxCall() method';

        return $result;
    }
</code></pre>

<p>That should be all you need</p>

CC BY-SA 4.0
2018-12-04T15:16:11.190Z
2018-12-04T15:16:11.190Z
Hector
<p>This is a pretty simple test before I implement some larger functionality. Eventually this will be just a glorified upload form via ajax.</p>

<p><strong>Part 1 - Ajax post</strong></p>

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

<p><strong>Part 2 - Plugin</strong></p>

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

<p><code>$event-&gt;rules['upload2'] = 'plugin/default/upload';</code></p>

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

<pre><code>public function actionUpload()
{        
    $response_array['status'] = 'success';  
    $response_array['post'] = $_POST;
    return json_encode($response_array);
}
</code></pre>

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

<p>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)</p>

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

<plugin-development><ajax><craft3><javascript>
Craft 3 - ajax request to plugin
# Craft 3 - ajax request to plugin

(Asked by: username_0 on 2017-11-19)

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

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?

**Tags:** plugin-development, ajax, craft3, javascript

---

## 2 answers

### Answer by username_1 on 2017-11-19. Score: 5 | Accepted answer

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>

> **Comments:**
> **username_2**: The link for the CSRF changes for Craft 3 is broken.  
> **username_3**: Yeah, link is still broken. I am looking for the same information today.  
> **username_1**: Updated link...  
> **username_4**: @BradBell I'm building craft3 pwa app and issue with taken caching. Is there a way to check the token for each page load?  

---

### Answer by username_5 on 2018-12-04. Score: 2

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

And finally in the controller
public function actionAjaxCall()
     {
        $result = 'Welcome to the DefaultController actionAjaxCall() method';

        return $result;
    }

That should be all you need


---

