How to rewrite all url using .htaccess in laravel - .htaccess

I have a laravel app. In my app there are some products which are already indexed on google.
I can change products URL through Routes but when a user comes using the google search engine there is a server error because I have changed all product URLs through routes.
Now I am trying to redirect the old URL to the newer by .htaccess
The original URL is www.xxx.com/product/samsung-galaxy-a90.php
I want to redirect it to www.xxx.com/samsung-galaxy-a90
RewriteRule ^product/([0-9a-zA-Z_-]+) product/$1.php [NC,L]
My route is:
Route::get('product/{proslug}.php', 'PostController#singlepro')
->name('singlepro');
Now what is the right .htaccess code to do this?

You don't need to modify the .htaccess, you can do all with laravel routes, e.g.:
Route::get('/product/{proslug}.php', function ($proslug) {
return redirect('/'.$proslug, 301); // Moved Permanently
return redirect('/'.$proslug, 302); // Moved Temporarily
});
// Other routes
// Last route because is a catch all route
Route::get('/{proslug}', 'PostController#singlepro')
->name('singlepro');
You only need to put the 'singlepro' route as the last one of your routes because is a catch all route.
With that routes in place every request to www.xxx.com/product/samsung-galaxy-a90.php will be redirected temporary (code 302) or permanently (code 301) to www.xxx.com/samsung-galaxy-a90 and to the PostController singlepro() function with parameter $proslug, e.g.:
class PostController extends Controller
{
public function singlepro($proslug)
{
// your code here
}
}

Hi you have to check AllowOverride if it is None so set it to All like
<Directory /var/www/project_folder/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
In addition, make sure that the rewrite module is enabled:
sudo a2enmod rewrite

Related

Options +Indexes of .htaccess not working

I have a website running on a server. It's just an index.html with a hello world text. Also, I have a folder named /vpn which contains various txt files and an index.html file.
If I try to access the URL domain/vpn, it shows me the content of index.html.
I just need to show the files inside the folder vpn when the user tries to access domain/vpn.
I created an .htaccess file with the next content in the root:
RewriteEngine on
<If "%{REQUEST_URI} == '/vpn/'">
DirectoryIndex disabled
Options +Indexes
</If>
When I try to access to vpn, it shows me a 404 error, the requested URL was not found on this server.
.htaccess is applying the DirectoryIndex rule (If a delete it, it shows me index.html content again), but not the Options +Indexes one.
I tried the same example in localhost (with XAMPP) and it's working fine.
What can be the problem?
PD: This is the content of apache2.conf file:
When I try to acces to vpn, it shows me a 404 error, the requested URL was not found on this server.
If you are getting a "404 Not Found" then it would imply that mod_autoindex is not actually installed on your server (consequently Options +Indexes has no effect - although it would seem from your server config that Indexes is perhaps already enabled).
mod_autoindex is the module responsible for generating the directory listings.
I created an .htaccess file with the next content in the root:
Personally, I would create an additional .htaccess file in the /vpn directory instead:
DirectoryIndex disabled
Options +Indexes
And disable Indexes (and set DirectoryIndex) in the root .htaccess file.
NB: RewriteEngine has no place here, unless you are overriding a parent config.
If I try to access the url "domain/vpn"
Note that you should be requesting domain/vpn/ (with a trailing slash). If you omit the trailing slash then mod_dir issues a 301 redirect to append it.

Redirect specific page on specific domain alias to https/SSL with .htaccess

Redirect specific page on specific domain alias to https/SSL.
The webhosting is setup with multiple domain aliases on the same vhost.
It needs to redirect a specific page on a specific domain alias to https.
domain-a.com
domain-b.com
domain-c.com
http://www.domain-c.com/contact needs to redirect to https://www.domain-c.com/contact
The other domains, domain-a.com and domain-b.com don't need to redirect /contact to https
Depending on your setup the most efficient way to do this would be in the code of the web page.
In php you could use the example below:
if(!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == ""){
$redirect = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("HTTP/1.1 301 Moved Permanently");
header("Location: $redirect");
}
But other options are also possible. For example for IIS you could make a rule in the web.config to match the certain page and redirect it to HTTPS.
Basic redirection in a .htaccess should work for you then.
redirect /contact https://www.domain-c.com/contact
There are prettier ways to do this in a .htaccess file but don not have an environment to test it before posting.

Redirect all requests to base URL without using .htaccess

When I browse example.com/img it shows all the directory contents. This leads to security problem . How to redirect these kind of url requests to example.com but without using htaccess
Best practice usually suggests adding these lines to your Apache config to disable directory listing:
<Directory />
Options -Indexes
Order allow,deny
Allow from all
</Directory>
But this will simply deny users access to the URL example.com/img. If you'd like to redirect as well, you could add an index.php file to each directory you'd like to redirect from in addition to making the Apache config change. The index.php file should contain:
<?php
header("Location:".$_SERVER['DOCUMENT_ROOT']);

Redirecting all RESTful requests to domain root without changing URL

As the title says, I want all requests
domain.com/something
domain.com/somethting/else
domain.com/a/third/thing
to redirect to
domain.com
BUT still show the original URL since I want to use them as parameters. I've tried these two ideas but the URLs end up displaying
domain.com
I found the answer here at Gareth Jones's blog:
Passing all requests to a single PHP script
I needed all requests with a certain URL prefix to be handled by a single script. This was easily solved using the following URL re-writing rule in a .htaccess file:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^.*$ index.php
Note that I had to enable the mod_rewrite module in Apache and ensure that directives could be overridden with the following:
<Directory /var/www/>
AllowOverride All
</Directory>
Determining the full requested URL
Another requirement of my application complicated by URL rewriting was that I needed access to the full URL. I achieved this with the following bit of code:
$protocol = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
$location = $_SERVER['REQUEST_URI'];
if ($_SERVER['QUERY_STRING']) {
$location = substr($location, 0, strrpos($location, $_SERVER['QUERY_STRING']) - 1);
}
$url = $protocol.'://'.$_SERVER['HTTP_HOST'].$location;

Backbone.js save gets '404 not found' on Slim.php

I have created a Backbone.js model and want to save an instance to my MySql database.
var Website = Backbone.Model.extend({
defaults: {
"title":"default title"
},
urlRoot : './websites'
});
var website = new Website();
website.save();​
I am using Slim.php to create a Restful API to my database. Here is the beginning of websites\index.php:
<?php
require 'Slim/Slim.php';
$app = new Slim();
$app->get('/websites', 'getWebsites');
$app->get('/websites/:id', 'getWebsite');
$app->post('/websites', 'addWebsite');
$app->put('/websites/:id', 'updateWebsite');
$app->delete('/websites/:id', 'deleteWebsite');
$app->run();
My save() triggers a POST which gets "moved permanently":
Request
URL:localhost/SAMPLE-CODES/backbone.js-mysql-reading-json/websites
Request Method:POST Status Code:301 Moved Permanently
Then I see a second http request sent:
Request
URL:localhost/SAMPLE-CODES/backbone.js-mysql-reading-json/websites/
Request Method:GET Status Code:404 Not Found
My question is: why is this request not triggering the call to the 'addWebsite' function ?
I see that the second http request is a GET, when it should be a POST, but even then there is a route for that...
I have a folder /websites/
I also set the the .htaccess and http.conf as per the Slim routing documentation:
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
http.conf
<VirtualHost *:80>
<Directory "c:/xampp/htdocs/SAMPLE-CODES/backbone.js-mysql-reading-json/websites/">
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Edit:
The call to model.save() triggers an http POST to
localhost/SAMPLE-CODES/backbone-mysql-reading-json/websites
.
This gets a '301 Moved Permanently' with response header says:
localhost/SAMPLE-CODES/backbone-mysql-reading-json/websites/
.
I assume this is due to the Slim recommended .htaccess settings.
Question: Is this OK to have this '301 Moved Permanently', or do I already have an issue here?
Then I see 2nd http GET to
localhost/SAMPLE-CODES/backbone-mysql-reading-json/websites/
Update:
I am still getting a 301 on
localhost/SAMPLE-CODES/backbone-mysql-reading-json/websites
, then a GET to
localhost/SAMPLE-CODES/backbone-mysql-reading-json/websites/
This second request works on a browser and returns
[{"id":"1","title":"titre site 1"},{"id":"2","title":"titre site 2"}]
So that would be the response for all records, but I wanted to save 1 record.
It seems the redirect 301 is wrong.
I have a feeling it is due to Slim not finding a matching route (Slim_Exception_RequestSlash would trigger a 301).
But why my Slim script not find the route?
The request for
localhost/SAMPLE-CODES/backbone-mysql-reading-json/websites
is matched by:
$app->post('/websites', function() {
I also use SlimPHP and have a setup just like yours.
What PHP are you using? If you're using a version >= 5.3 then the way you're defining your routes would be incorrect. For a newer PHP, try this:
$app->get('/websites', function () {
// your code to execute
});
Everything else about your setup looks pretty normal to me.
Problem solved thanks to orangewarp and this question:
Why do I get a 301 redirect to folder name with slash?
Solution was to add DirectorySlash Off in the .htaccess:
My updated .htaccess (where the app calls Slim.php):
RewriteEngine On
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

Resources