I am working on basic CRUD using Laravel. I am getting MethodNotAllowedHttpException when using PUT and DELETE method in Laravel form action. GET and POST action methods work fine.
HTML form only accept either GET or POST method so you can't use PUT and DELETE in form method. However, if you want to use PUT or DELETE then laravel provide Form method spoofing like this
<input type="hidden" name="_method" value="PUT">
Here is the form example
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
Short form
<form action="/foo/bar" method="POST">
#method('PUT')
#csrf
</form>
Route
Route::put('foo/bar', 'FooController#bar');
Check details here https://laravel.com/docs/5.6/routing#form-method-spoofing
Related
I am a beginner in laravel framework. Now I am creating a form which will send post request to /abc.php. However, after submitting the form, error unknown server error with status 419 is reported.
I have googled about this issue and I figured out that it was caused by csrf_token. I tried to except verify csrf token in this route and forms were submitted successfully.
Therefore, I have added {{ csrf_field() }} after the <form>tag and submit the form again but the form submit failed. Except not verifying the csrf token in my form, what can cause this problem? Thank you very much!
My route
Route::post('/abc.php','formSubmitController#submit');
My form
<form class="myform" name="myform" id="myform" method="post" action="/abc.php" onsubmit="return validation();" enctype="multipart/form-data">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
....
</form>
try so...
Route::post('/abc','formSubmitController#submit')->name('abc');
<form class="myform" method="post" action="{{route('abc')}}" onsubmit="return validation();" enctype="multipart/form-data">
#csrf
....
</form>
I am not using resource controller.
The route:
Route::delete('/deleteTag/{tag}','Controller2#deleteTag');
The controller function:
public function deleteTag(Tag $tag){
$Tag = Tag::where('id', $tag->id)->get()->first();
$Tag->delete();
return redirect()->action('Controller2#main');
}
The call:
<form method="delete" action="http://***/public/deleteTag/{{$tag->id}}">
{!! Form::token() !!}
<button type="submit">delete</button>
</form>
The program returns a MethodNotAllowedHttpException.
Thank you.
You may try this (Notice the hidden _method input):
<form method="post" action="http://***/public/deleteTag/{{$tag->id}}">
{!! Form::token() !!}
<input type="hidden" name="_method" value="DELETE">
<button type="submit">delete</button>
</form>
Check Form Method Spoofing.
Update:
In the latest versions of Laravel, it's possible to use blade directives for csrf and method in the form, for example:
<form method="post" action="...">
#csrf
#method('DELETE')
<button type="submit">delete</button>
</form>
It's better to change your route to this mode:
Route::resource('tags','TagController');
You should register a resourceful route to the controller. This single route declaration creates multiple routes to handle a variety of RESTful actions on the Tag resource.
Remember, since HTML forms can't make PUT, PATCH, or DELETE requests, you will need to add a hidden _method field to spoof these HTTP verbs.
<input type="hidden" name="_method" value="DELETE">
or add this in your form
{{method_field('DELETE')}}
As I am new to laravel framework, I have a query, I am using <form> tag in blade template so that I can delete the data from table.
I am using this the below code of form tag to delete the data
<form action="{{ route('admin.states.update',$data->state_id) }}" id="form_sample_2" class="form-horizontal" novalidate="novalidate" method="PUT">
Here I have used method as PUT, but browser is automatically considering it as GET request, I found some questions on stackoverflow where many of them said PUT & DELETE is not detected by browser.
So using Laravel Facade Form , this problem is solved
{!! Form::open(array('route'=>['admin.states.update',$data->state_id],'role'=>'form','method'=>'PUT')) !!}
The above code work as intended but my query is I don't want to use Formfacade in Laravel , I want to use first type of HTML code for form opening.
Is there any other method by which I can use PUT method in HTML Form Tag without using any Form FAcade in Laravel.
set form method to post and add a hidden input as following
<input type="hidden" name="_method" value="put">
and also make sure to add
<input type="hidden" name="_token" value="{{ csrf_token() }}">
If your ValidateCSRF middleware is enabled.
To make my life simpler in a huge website, can I do this?
Route::get('view/{id}', 'PostController#show')->name('post');
Route::delete('view/{id}', 'PostController#delete')->name('post');
Route::post('view/{id}', 'PostController#save')->name('post');
And then in my form, I can do this.
<!-- Delete Form -->
<form method="post" action="{{ route('post', $post->id) }}">
<input type="hidden" name="_method" value="DELETE">
<button type="submit">Delete</button>
</form>
<!-- Edit Form -->
<form method="post" action="{{ route('post', $post->id) }}">
<input type="hidden" name="_method" value="PATCH">
<button type="submit">Edit</button>
</form>
<!-- Etc -->
Can I do this? Is this recommended?
Yes, in fact you can use the following to keep your route file clean: https://laravel.com/docs/5.2/controllers#restful-naming-resource-route-parameters
Route::resource('foobar', 'FooBarController');
This will auto generate RESTful routes for you:
if you run php artisan route:list you can see all the HTTP routes.
I have a PostController in which I have all RESTful methods. I can generate route to delete method by defining method in form tag like below,
<form action="{{route('post.destroy', [$post->id])}}" method="POST">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" value="Delete">
</form>
But I need to generate same route with link,
Delete
thanks.
You have to create an link, which triggers your Form Submission with JavaScript. You cant create an Link with "POST" instead of "GET" Method.
As Basic example without JQuery and proper separation of code, add this to your template.
Add an ID to you Form "myform"
<script type="text/javascript">
function submitMyform()
{
document.myform.submit();
}
</script>
And change your link to:
Delete
if you want to show only the link, use hidden form elements.
This should do it:
Delete