Laravel vue axios is action method and csrf needed for ajax forms - laravel

I am posting a ajax from in Laravel using axios and vue, I have a #click="postData" button in the form that toggles a axios post request:
postData() {
axios({
method: 'post',
url: appJS.base_url + '/comment',
responseType: 'json',
data: comData
})
.then(function(response) {
})
But do I still need to add the action, method and csrf to my form?
<form action="{{ url('/comment') }}" method="POST">
{{ csrf_field() }}
</form>
vs
<form></form>
Everything works fine just using <form></form> but I wonder if there are any pros/cons?
I am making a ajax call in the background since I dont want the whole page to reload

You definitely don't need action and method attributes on form tag, because they are already defined on your axios call.
As for the csrf_field(), you probably still need it, because Laravel has a preconfigured middleware called VerifyCsrfToken. But it depends if you use it or not.

you can using event form in vuejs, you need't using ajax, you can try the following code, but if laravel + vuejs, need add Enable CORS for a Single Route in laravel:https://gist.github.com/drewjoh/43ba206c1cde9ace35de154a5c84fc6d
export default{
data(){
return{
title:"Form Register",
}
},
methods:{
register(){
this.axios.post("http://localhost:8888/form-register",this.formdata).then((response) => {
console.log(response);
});
},
}
}
<form action="" method="post" v-on:submit.prevent="register">
<div class="panel-heading">{{title}}</div>
<div class="form-group">
<button type="submit" class="btn btn-danger">Register</button>
<button type="reset" class="btn btn-success">Reset</button>
</div>
</form>

Related

Sharing reCaptcha token between alpine and livewire

I am trying to build a reCapture component for a Laravel application using Livewire and Alpine and I can't figure out how to pass the recaptcha token value into the livewire component to complete the validation.
If I understand correctly this is because when I submit the form I am setting a hidden input value (recaptchaToken), however, livewire can not access hidden inputs so I need to use wire:model to bind to the data.
How can I pass the recaptchaToken.value in the submitForm() method, or how do I set the $recaptchaToken value with wire:model
<form x-data="{
execute(){
grecaptcha.ready(() => {
grecaptcha.execute('{{ env('RECAPTCHA_SITE_KEY') }}', { action: 'contact' })
.then((token) => {
{{-- how can i bind to wire:model instead of setting input.value ??? --}}
this.$refs.recaptchaToken.value = token;
})
})
}
}"
x-on:submit.prevent="execute" class="flex-col gg"
{{-- how can I access the recaptchaToken.value to pass into the submitForm() method ??? --}}
wire:submit.prevent="submitForm()">
<input wire:model="recaptchaToken" type="hidden" name="recaptchaToken" x-ref="recaptchaToken">
<button type="submit" class="w-fc btn primary">SUBMIT</button>
</form>

How to convert laravel form delete into string to use it on return controller?

I have delete form but I can't use directly on blade cause I am using datatable and it just there to put the code of the form.
This is the code of delete that I want to copy
<form action="{{ route('admin.users.destroy', $user->id)}}" method="post">
#csrf
#method('DELETE')
<button class="btn btn-danger" type="submit">Delete</button>
</form>
and I want to put/swap in the red circled image below cause <a href="'.route('admin.users.destroy', $user->id).'" used GET and not DELETE method.
I believe you need to use the ajax call instead of call it through the link you can ajax call as below and it will DELETE resource.and then refresh the datatable
$.ajax({
url: '/admin/users/4',
type: 'DELETE', // user.destroy
success: function(result) {
// Do something with the result
// refresh the datatable
}
});

Laravel normal login with vuejs using axios returns error Request failed with status code 422

Am trying to use laravel and vue js with axios
Previously this was my login form
<form name="login-form" method="POST" action="{{ route('login') }}">
//username and password fields
</form>
Which works perfectly one can login
Now i would like to use vuejs in a similar way without making my app a single page app
so i have resulted to making a login component
<template>
<form name="login-form">
<input type="email" v-model="email" class="form-control" autofocus>
<input id="password" type="password" v-model="password" required>
<button type="submit"
class="btn btn-dark btn-sm"
#click.prevent="login"
:disabled="disableform">
{{submitted?"Logging you in .....":"Login"}}
</button>
</form>
</template>
Now script part
<script>
export default {
data: () => ({
email :'', password:'', remeberme:true, submitted:false
}),
methods: {
login() {
//do other stuff like disabling buttons...etc
axios.post("/login", {email:this.email, password:this.password})
.then(
(res)=>{
///showing sweet alert then
// settimout for 3 sec the
window.location.href="/dashboard";
},
(err)=>{
//show sweet alert of failed login
}
)
},
}
Now whenever i make the login post request an getting an error
Request failed with status code 422
I would like to proceed with the laravel vuejs workflow(with authentication sessions) but not an api jwt token request format.
What could be wrong or is this possible?
It's a validation error. check you laravel controller regarding post/put function.
Request failed with status code 422
When laravel fail the validation then it appears.
You need to use a csrf_field in your form, like this:
<input type="hidden" name="_token" :value="csrfToken">
And define it in your script:
data() {
return {
csrfToken: ''
}
},
created() {
this.csrfToken = document.querySelector('meta[name="csrf-token"]').content;
}

Vue-Resource gives TokenMismatchException in Ajax POST call

Please note, I'm using the Laravel framework.
Also please note, there are similar questions on SO, I've checked them, but wasn't able to solve my problem based on those solutions...
Even though I set my CSRF token right to my knowledge, I'm not sure why it won't work.
When checking the console, it seems I have 3 cookies: two Request cookies of which one is called XSRF-TOKEN and one is called laravel_session. And one respone laravel_session cookie. All have a different value!!!
My Vue:
new Vue({
el:'body',
http: {
root: '/root',
headers: {
'X-CSRF-Token': $('meta[name=_token]').attr('content')
}
},
});
My head:
<meta name="_token" content="{!! csrf_token() !!}"/>
My Vue component addNew method:
Vue.component('things',{
template:'#things-panel-template',
data(){
return {
list: [],
newThing: {
body: '',
// _token: $('meta[name=_token]').attr('content'),
// tried removing token from head meta and adding up here.
},
}
},
methods:{
addNew(){
var thing = this.newThing; // get input
this.newThing = {body:''}; // clear input
this.$http.post('/api/things/add',thing) // send
},
},
});
My route:
Route::post('/api/things/add',function(){
return App\Thing::create(Request::get());
});
And finally, the form in my Vue Template:
<form action="/things/add"
method="POST"
#submit.prevent="addNew"
>
<div class="form-group">
{{ csrf_field() }}
<label for="">Add</label>
<input type="text"
name="body"
id="task-body"
class="form-control"
v-model="newThing.body"
>
<button :disabled="!isValid"
class="btn btn-primary"
type="submit"
>Add</button>
</div>
</form>
Try this:
this.$parent.$http.post('/api/things/add', thing)
instead of
this.$http.post('/api/things/add', thing)
Or set default values using the global configuration:
Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name=_token]').attr('content');
I found the answer myself:
If you're gonna work with a vue-component, you should just add the token to that component instead. Otherwise it won't go with your ajax request.
So put this part underneath the template in the component:
http: {
root: '/root',
headers: {
'X-CSRF-Token': $('meta[name=_token]').attr('content')
}
},
Do this to check if your token was properly sent inside the headers:
Go to google chrome, open dev-tools, go to the network tab and Reload.
Make the ajax call and look at the file added in the network tab, open it and go to the 'Headers' tab.
Look at the bottom where it says: 'Request Headers' and check if the token was properly added in the request.

How laravel set path for ajax and forms

I have simple question:
How laravel set correct path for ajax or form action?
I have my laravel instalation in
localhost/laravel-test/public
Ok and lets say i have url opened: localhost/laravel-test/public/hello
<form method="post" action="some/very/long/path">
<input type="submit" value="just-test" />
</form>
Now i hit just-test button, and its always know where it should start routing - allways start from public/[route here].
I was try to do my own routing system, but i have problem because its going to addres:
localhost/my-framework/public/hello/some/very/long/path
It allways put after public my actual url, and then after form action..
So my question is how laravel know it should get
localhost/laravel-test/public/some/very/long/path
It works same for jquery ajax request for ex:
$.ajax({
url: "test.html",
context: document.body
})
Laravel console output:
localhost/laravel-test/public/test.html
My custom framework console output
localhost/my-framework/public/actualpath/test.html
For the form action you can use the url or route helper. Like so:
{{ url('very/long/path') }}
And for your front end part.
$('#form').live('submit', function(event) {
$form = $(this);
$.ajax({
url: $form.attr('action')
});
});
I think this is what you're looking for.
In routes.php
Route::post('some-very-long-uri', ['as' => your-name', 'uses' => 'YourController#method']);
Then you can do something like that
<form method="post" action="{{ route('your-name') }}">
<input type="submit" value="just-test" />
</form>
and for ajax
$.ajax({
url: "{{ route('your-name') }}"
});

Resources