I am writing a laravel api and when I try to make delete and post requests I keep getting a method not allowed exception. Where should I be looking to diagnose this problem?
I have read though most of the other posts on this issue and here is what I have tried/looked at.
• Made sure the route syntax was correct
• Made sure it didn't conflict with another route
• Made sure I was using the correct route (ran php artisan route:list to
double check)
• Modified the .htaccess folder (maybe I did this incorrectly) to allow GET, POST, PUT, DELETE
Here is what the route looks like in api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::delete('delete/{id}', 'LoginController#delete');
Route::get('stuff', 'LoginController#index');
Route::get('stuff1/{Username}', 'LoginController#show');
here is the function in the controller
public function delete(Request $request, $id) {
$user = Login::find($id);
$user->delete();
return "204";
}
here is my .htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
</IfModule>
I can get around this issue by changing Route::delete() to Route::get() and achieve the same functionality but this doesn't seem like standard practice.
You have to set ajax type POST but send a parameter named _method with value delete like this:
$.ajax({
type: "POST",
data:{
_method:"DELETE"
},
url: productRoute,
headers: { 'X-CSRF-TOKEN' : productToken }
});
Or because you use laravel html form helper so it generates _method hidden input automatically so you'd better send all your form inputs such as token and method like this:
function()
{
var formData=$('#yourForm').serialize();
$.ajax({
type: "POST",
url: productRoute,
data:formData
})
});
Related
I have to create an API in PHP, which I have never done before. I have a index.php in my root folder which contains a form. A button click activates an AJAX Request to read all entries and a form can be filled out to send data. I will also have DELETE and update.
ajaxcall.js
// GET to retrieve
var req;
req=new XMLHttpRequest();
req.open("GET", 'src/api/v1/posts',true);
req.send();
//post with ajax
$.ajax({
type:"POST",
url: "src/api/v1/posts",
data: test,
ContentType:"application/json",
success:function(){
alert('successfully posted');
},
error:function(){
alert('Could not be posted');
}
});
I have a folder src/api/v1 in there I want the endpoint file api.php which handles the different requests. I now need all the AJAX calls to be resend to api.php which sits inside that v1 folder. I created an .htaccess which is stored in also stored in src/api/v1. I added the following:
.htaccess
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule src/api/v1/(.*)$ src/api/v1/api.php?request=$1 [QSA,NC,L]
Unfortunately I get a 404 not found, it just does not seem to re-write the URL to the api.php so it is looking for /posts which does not exists. What am I doing wrong?
Actually you should store the .htaccess on the root directory, otherwise Apache will not know that there's an .htaccess under /src/api/v1, so apache will look for the directory src/api/v1/posts and as is it's not found a 404 error will be returned.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule src/api/v1/(.*)$ /src/api/v1/api.php?request=$1 [QSA,NC,L]
</IfModule>
how to create route in laravel for the below 2nd option....
http://localhost:8048/
http://localhost:8048/content/645668/nice-up-civic-poll.html
1st it redirects to home page which is correct for me.
2nd I need to get what ever comes after 8048/
so basically content/645668/nice-up-civic-poll.html is a parameter which I need to deal with it separately and its dynamic link.
Route api in laravel :
Route::get('/', 'HomeController#index');
www.example.com will load home page with all stories.
The below links as an example should get the value after www.example.com/ basically its a story/article link so when that comes specific story will be displayed.
www.example.com/content/645668/nice-up-civic-poll.html
www.example.com/content/283206/something-here.html
www.example.com/content/234323/good-nice.html
www.example.com/content/451425/breakup-actor.html
www.example.com/content/365412/accident-occured.html
So basically get everything after domain name which is using apache server.
.htaccess file
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
If you want a home route and then every other URI to go to a single Controller method you can make a catch-all route:
Route::get('{catch}', 'SomeController#action')->where('catch', '.*');
This would catch any URI that doesn't match any previously defined route.
If you want everything to go to one place:
Route::get('{catch?}', ....)->where(...); // optional param
Post about creating a catch all route, answer using regex conditions on parameter:
SO - How do I make a Catch-All Route in Laravel 5.2
Update:
If these URIs you need to catch all have the same format,
www.example.com/content/645668/nice-up-civic-poll.html
you can register a route to match that format instead of catching everything possible:
Route::get('content/{id}/{slug}', function ($id, $slug) {
...
});
try using $request helper..
$leftbehind = str_replace($request->getHost(),'', $request->fullUrl());
or try this..
$request->getRequestUri();
Use $request->path()
The path method returns the request's path information. So, if the incoming request is targeted at http://example.com/foo/bar, the path method will return foo/bar
https://laravel.com/docs/5.5/requests#request-path-and-method
You can use The Request::path() to get the current url.
https://laravel.com/api/5.5/Illuminate/Http/Request.html - Check this for all the options available for Request.
eg: If you want to just check whether the users is in some url or not use this - Request::is('/url') // This will return true or false
You can use php's built in function, parse_url to retrieve content/645668/nice-up-civic-poll.html.
parse_url($url, PHP_URL_PATH)
I have a route group for the prefix admin. I want that if the URL http://www.example.com/admin/ is entered it by default loads the login page residing at http://www.example.com/admin/login. The login page is actually a controller, but I don't mind if the admin/ redirects to admin/login or routes to its controller directly. From other answers I saw here it seems that redirection is better to make sure links are not messed up.
I have tried various solutions with both routing and redirection, including the solution suggested here but I am alwas getting Error 404. What is the recommended proper way to achieve this?
My route group looks like this:
Route::group(array('prefix' => 'admin', 'namespace' => 'MyNamespace\Controllers\Admin'), function()
{
//the following work fine
Route::get('login', array('uses' => 'AdminLoginController#showLogin'));
Route::post('login', array('uses' => 'AdminLoginController#doLogin'));
Route::get('logout', array('uses' => 'AdminLoginController#doLogout'));
//other resource routes for the respective admin pages
});
Outside the route group I added the following, so that even http://www.example.com/admin without the trailing slash goes to the login page, which works fine.
Route::get('admin', function() { return Redirect::to("admin/login"); });
The problem is with http://www.example.com/admin/ that is giving Error 404. I tried all the following (separately obviously), and none works. All of them were inside the route group.
Route::get('/', function() { return Redirect::to("admin/login"); });
Route::get('', function() { return Redirect::to("admin/login"); });
Route::get('/', function() { return Redirect::to("login"); });
Route::get('', function() { return Redirect::to("login"); });
Route::get('/', array('uses' => 'AdminLoginController#showLogin'));
Route::get('', array('uses' => 'AdminLoginController#showLogin'));
I also tried this outside the route group:
Route::get('admin/', function() { return Redirect::to("admin/login"); });
None of them work. What is the right way to set a default route for a route group with a prefix subdirectory?
use this code in .htaccess
so your server will redirect url's with trailing slashes to url without.
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
# redirect everything to url without trailing slash
RewriteCond %{HTTPS} =on
RewriteRule ^(.+)$ - [env=ps:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.+)$ - [env=ps:http]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_METHOD} ^GET
RewriteRule ^(.+)/$ %{ENV:ps}://%{SERVER_NAME}/$1 [R=301,L]
# pretty urls
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>
by default laravel firstly did redirection, but later was removed.
I have a simple API in Laravel. The routes file is like so:
<?php
Route::resource('airports', 'AirportController');
Route::resource('flights', 'FlightController');
Route::resource('reservations', 'ReservationController');
Route::get('auth', 'AuthController#index');
Route::post('auth', 'AuthController#store');
Route::delete('auth', 'AuthController#destroy');
The filter's file has a custom filter added like so:
Route::filter('auth_token', function()
{
$auth_token = Request::header('Authorization');
if(!AuthToken::where('auth_token', '=', $auth_token)->first()){
return Response::json([], 401);
}
});
All the resources need to pass before the auth_token filter. Now this works great on my local machine but as soon as I try it on my server, everything is unauthorized, even if I pass a valid token. The problem I figured by dd($auth_token) in my custom filter is that it is returning null which means that my server is not accepting the header for some reason.
My .htaccess file looks like so:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "*"
</IfModule>
I am using Postman REST client to test my application. There is only one user in the system with email 'admin#admin.com' and password 'admin12345'. You can POST these details to the /auth route and get an access token granted which can then be used to fetch other resources in the system.
The application is hosted here. What am I doing wrong?
The order of the routes might be an issue. try inverting like this and see if it works ...
Route::get('auth', 'AuthController#index');
Route::post('auth', 'AuthController#store');
Route::delete('auth', 'AuthController#destroy');
Route::resource('airports', 'AirportController');
Route::resource('flights', 'FlightController');
Route::resource('reservations', 'ReservationController');
I have a PHP program written on code igniter that needs your help! Have been trying for 3 weeks!
I have the htaccess mod rewrite to make http://www.sampleurl.com/controllername instead of http://www.sampleurl.com/index.php/controllername
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/$0 [PT,L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 /index.php
</IfModule>
I have a controller for Dashboard (currently used for testing the session.)
public function index()
{
$is_logged_in = $this->session->userdata('fb_session');
$data = array(
'fb_data' => $is_logged_in,
);
if (!isset($is_logged_in) || $is_logged_in != true){
redirect('/error');
}
}
Below is the function that suppose to kill the current session and redirect to dashboard page.
$('#logoutbtn').click(function(){
$.ajax({
type:"POST",
url: "/fbcontroller/killsession",
datatype: "json",
success: function(){
alert("Logout");
}
});
});
public function killsession(){
$this->session->sess_destroy();
redirect('/dashboard');
}
Problem 1: as I redirect from function in 1 controller to another, the redirection fails here. Instead of directing to dashboard, the firebug displays 404 error, page not found. And in the response, it displays all the HTML code of /error page. Does it mean that the redirection works? If yes, why wouldn't it display on browser?
Problem 2: session destroyed, but logged in page stays even as I refresh (F5).
For htaccess I suggest:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php/$1 [L,QSA]
And know that when you kill session CI will create a new 1 on your next Page load (in your case on the redirect) .. Session isn't just for user logins.
Don't forget at app/config/config.php to set
$config["index_page"] = '';