Laravel. MethodNotAllowedHttpException in RouteCollection.php - php

There is a 2 language version on the site, when you turn on Rus the language is added to the URL "/ru" ie it will be http://site/ru, but at the same time, all attempts to send the form end with an error - "MethodNotAllowedHttpException in RouteCollection.php", in the original languages ​​http://site form Normally Are working
My forms:
<form action="/callback" method="post">
Route::post('/callback', 'ApiController#callback');

By registering that route, you're explicitly asking for a POST request, any other method is not allowed.
If you can't control the incoming request's method, then you should try using
Route::get or Route::any (I wouldn't recommend the last one if you're creating an API).
If you are confused about how routes work, I recommend you to use named routes, so you're always sure you're pointing the form to the right direction:
Route::post('/callback', 'ApiController#callback')->name('api.callback');
And then use it for your form in the view just like
<form method="POST" action="{{ route('api.callback') }}">
Or if you don't want to give it a name, just use the action helper
<form method="POST" action="{{ action('ApiController#callback') }}">

Related

Laravel 8.0's Route::post renders a blank page, and same route with get works

I'm new-ish to Laravel.
I have this form :
<form action="{{ route('foo.store', ['idFoo' => $foo->id]) }}" method="POST" accept-charset="UTF-8">
and this route :
Route::post('/foo/store/{idFoo}', [App\Http\Controllers\FooController::class, 'fooStore'])->name('foo.store');
Also, I added the #csrf, it's not the problem.
So, when this route is used, it renders a blank page , but if I change both "post" to "get", it works perfectly (btw the method fooStore is just dd('test')).
With the "post" mode, it won't even look which controller I'm using or anything.
Route post = blank page. No errors, nothing.
EDIT : I've found out that the route is not the problem, but the form "post" action is. When the action is "post", it renders a blank page, whatever the route type. But it works perfectly in "get" action.
try this
<form action="{{ url("/foo/store")}}/{{$foo->id}} method="POST" accept-charset="UTF-8">
#csrf
</form>
hope its work
Try to execute this command:
php artisan route:cache
SOLVED : This is the weirdest thing. For an unknown reason, change
Route::post('/foo/store/{idFoo}'
into
Route::post('/foo/store/bar/{idFoo}'
solved the problem. I have no clue why.

Trying to use PATCH method works with AJAX but not with a regular html form

I'm currently trying out http://altorouter.com/ and it's working well for me so far, except for this one issue I'm having
My route is set up like this:
$router->map( 'PATCH', '/admin/pages', 'pageController#update');
If I use the following jquery, the route works perfectly:
$.ajax({
type: "PATCH",
url: "/admin/pages",
data: {page_items:page_items, page_name: 'test_page'},
success: function(returned_data)
{
console.log(returned_data);
}
});
However, no matter what I put in my HTML I can't get a regular form to submit in a way it accepts as PATCH:
<form action="/admin/pages" method="post">
<input type="hidden" name="form_function" value="edit_theme">
<input type="hidden" name="_METHOD" value="PATCH">
<button type="submit">Save Page</button>
</button>
I've tried "_METHOD", "_method", "method" etc. None of them work.
I've also tried
method="PATCH"
but that only causes it to do a GET.
When I echo the $_SERVER['REQUEST_METHOD'] on the target page I get "PATCH" for the ajax, but just "POST" for the form. Hope someone can help.
In short, you cannot.
As you'll see in the W3 Spec
The only valid methods for HTML based forms are "GET" and "POST".
However you can work around this if you wish, on the server side instead. Theres a great article about how Laravel does it here: Theres no Put/Patch Delete Methods
A quick snippet of code from that article:
<form method="POST" action="" accept-charset="UTF-8">
<input name="_method" type="hidden" value="PUT">
</form>
<form method="POST" action="" accept-charset="UTF-8">
<input name="_method" type="hidden" value="PUT">
</form>
If you are not using Laravel and want to build a form manually, you cannot use PUT/PATCH – there’s just no such methods supported by forms in browsers – it’s only GET and POST. So how does Laravel make it work with {{ Form::create([‘method’ => ‘PUT’]) }}?
Actually, under the hood the generated HTML looks like this:
That’s right, Laravel constructs a hidden field with name _method and
then checks it upon form submittion, routing it to the correct
Controller method.
So if for any reason you would need to build the FORM tag yourself,
don’t put (same applied to patch and delete) – it
just won’t work. Instead add hidden fields, if necessary.
So back to your issue, Altorouter. It appears their documentation is rather lacing the best guide I can find for you is here https://recalll.co/app/?q=rest%20-%20PHP%20detecting%20request%20type%20(GET%2C%20POST%2C%20PUT%20or%20DELETE)%20-%20Stack%20Overflow it might be worth your while finding a better router, as Alto doesn't seem to have been updated in around 3 years.
Managed to find a working solution after digging around in the code. Altorouter's match method actually accepts a method parameter, which doesn't seem to be documented anywhere.
Where I used to have
$match = $router->match();
I now have:
if(isset($_POST['_method']))
{
$match = $router->match(null, $_POST['_method']);
}
else
{
$match = $router->match();
}

form update with file upload laravel

I'm having a bit of an issue when it comes to updating a form and and having an file input. Here is what I am working with.
I have a form in laravel 5.1 which has a post method and a hidden 'Patch' method. This works as is should updating the fields that are in the form. However, when it introduce:
<input type="file" id="profile_picture" name="image_url" />
into the form, i get a:
MethodNotAllowedHttpException in RouteCollection.php line 218:
laravel error. I have tried changing the
<input type='hidden' name='_method' value='PATCH'>
to PUT and it still doesnt like it.
My form looks like this:
<form action='{{url("profiles/$user->id")}}' method="post" class="form-horizontal" enctype="multipart/form-data">
route resource looks like this:
Route::resource('profiles', 'ProfilesController');
I can't figure out what I am missing here...Any help is much appreciated.
I believe it has to do with the exact route you are typing out in the "action" parameter matching up with the profile controller's update method.
Try changing
action'{{url("profiles/$user->id")}}'
to
action='{{ route("profiles.update", $user->id) }}'
Additionally, you could use the Laravel Collective HTML package to simply opening and closing of forms.
Also for POST Request types, you need to send the CSRF token along with your form data. If you are using laravel blade template in your view, you may use
{{ csrf_field() }}
which translates to
<input type="hidden" name="_token" value={{ csrf_token() }}
Please refer the documentation for this.

How to use form element in Laravel 5.2 without using form facade?

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.

Yii routing on form action

I have a problem where, when submitting my form, it seems to ignore my routing and redirects me to the Home instead.
In my main.php routing:
'<language\w+>/profile/<slug:[\w\-]+>' => 'profile/index',
'<language\w+>/<action:\w+>' => 'site/index',
My form:
<form action="<?php echo Yii::app()->getBaseUrl()."/".Yii::app()->language;?>
/profile/calendar" method="post">
Which outputs to
<form action="/domainname/nl/profile/calendar" method="post">
Note: domainname is there because I'm testing this on localhost.
However, when pressing the submit button it forwards me to the home instead of the correct page. Simply visiting /domainname/nl/profile/calendar in the browser does work and gives me the correct controller. I don't know why it isn't working in the form.
In a different form on the same website, I have the following, which again does work fine for the routing:
<form action="/domainname/nl/profile/info" method="post">
The difference between these 2 forms is that the last one is created through CActiveForm widget and the first one isn't.
Make simple post request to "/domainname/nl/profile/info" and watch for response headers. Or you can analyze existing requests with tcpdump or something simular
I managed to work around the issue by switching my manual form to use the CActiveForm widget after all. It seems I needed the yii_cs_csrf_token that is automatically generated by CActiveForm.

Categories