I have this form where the user should only type text inside a text area:
<form action="#" v-on:submit="postStatus">{{-- Name of the method in Vue.js --}}
<div class="form-group">
<textarea class="form-control" rows="5" maxlength="140" autofocus placeholder="What are you upto?" required v-model="post"></textarea>
</div>
<input type="submit" value="Post" class="form-control btn btn-info">
{{ csrf_field() }}
</form>
Then, I have this script code where I am using vue.js with ajax in order to pass that text into a controller and eventually save it into the database:
//when we actually submit the form, we want to catch the action
new Vue({
el : '#timeline',
data : {
post : '',
},
http : {
headers: {
'X-CSRF-Token': $('meta[name=_token]').attr('content')
}
},
methods : {
postStatus : function (e) {
e.preventDefault();
console.log('Posted: '+this.post+ '. Token: '+this.token);
$.ajax({
url : '/posts',
type : 'post',
dataType : 'json',
data : {
'body' : this.post,
}
});
}
},
});
However, this doesn't work so far, since there's this token mismatch exception. I don't know how to make it work. How to pass this token value to the controller. I have tried the following:
1) inside the form, I have added a vue name to the token:
<input type="hidden" name="_token" value="YzXAnwBñC7qPK9kg7MGGIUzznEOCi2dTnG9h9çpB" v-model="token">
2) I have tried to pass this token value into the vue:
//when we actually submit the form, we want to catch the action
new Vue({
el : '#timeline',
data : {
post : '',
token : '',
},
methods : {
postStatus : function (e) {
e.preventDefault();
console.log('Posted: '+this.post+ '. Token: '+this.token);
$.ajax({
url : '/posts',
type : 'post',
dataType : 'json',
data : {
'body' : this.post,
'_token': this.token,
}
});
}
},
});
... but in the console, vue doesn't even catch it :(
This leads me to the following error:
TokenMismatchException in VerifyCsrfToken.php line 68:
How do I fix it? Any ideas?
Very Easy Solution
Just add a hidden field inside the form. An ExampleNow add
csrf
variable inside script at the vue file, like this. (Remember, it must be inside data).N.B. You will see a meta tag in your
blade.php
file like this.If there is nothing like this, you need to place it there.
My solution to this is that all vue components get csrf token right before a request is made. I put this in my bootstrap.js file.
Then have a class CoolApp.php
I solved it thanks to these two answers:
1) First I read this one, which led me to
2) This second one.
So, in my form I keep this:
{{ csrf_field() }}
And inside the js file I only add the following (outside and above the Vue instance):
var csrf_token = $('meta[name="csrf-token"]').attr('content');
So the whole js code is:
A better way is simply to pass the csrf token via a slot into the vue component.
In blade.php file:
In MyVueComponent.vue
Simply, I would suggest to put this in your PHP file:
This way you're able to easily import your csrfToken from the JS part (Vue in this case).
Moreover, if you insert this code in your PHP layout file, you can use the token by any component of your app, since
window
is a JS global variable.Source: I got the trick from this post.