this is my first question here on stackoverflow because in the past I always found a question that described my problem perfectly.
But now they were not able to do that, so I decided to ask for help myself.
My goal is to display profiles, but the url shouldn't look like "/profile/show-profile.php?user=admin", just "/profile/admin".
So looked it up on google and found URL rewriting to be potentially useful, by editing the .htaccess file.
The problem is, it doesn't work. I already have some things in my .htaccess (redirecting to https and the 404-Page "/pagenotfound.php") and it seems like they don't work in combination.
# https redirecting
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^(.*)$ https://int-politics.com/$1 [R=301]`
# 404 page
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /pagenotfound.php
ErrorDocument 404 /pagenotfound.php
# URL REWRITING
RewriteEngine On
RewriteBase /profile/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ show-profile.php?user=$1
When I add the URL Rewriting part the 404-Page doesn't work anymore. Every site that doesn't exist just outputs "/pagenotfound.php" (see image -->)
Not-existing site just outputs /pagenotfound.php instead of showing it.
And the url-rewriting doesn't work too.
It would be wonderful if you could help me with this problem and tell me whats wrong. Thank you very much!
You usage of the RedirectBase is wrong. It should appear only once in such a distributed configuration file. Actually it is not required in this example at all ... Please take a look into the documentation for details on that: https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
Also it is vital to understand that the rewriting engine loops if a rule gets applied. And why that makes using the L or the END flag so important.
That probably is what you are looking for:
RewriteEngine On
RewriteBase /
# https redirecting
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://int-politics.com%{REQUEST_URI} [R=301,END]
# profile rewriting
RewriteRule ^/?profile/(\w+)$ /profile/show-profile.php?user=$1 [END]
# 404 page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /pagenotfound.php [END]
ErrorDocument 404 /pagenotfound.php
Best is to implement such rules in the central http server's host configuration. If you do not have access to that (read: if you are using a cheap hosting provider) then you can use a distributed configuration file instead, if the consideration of such files has been enabled (see the documentation for the AllowOverride directive on that).
Related
I have these htaccess rules and I want to convert them to nginx. I have tried online converters and different approaches but nothing seems to work. I am curious to see other opinions, to compare with everything I did by now and see if something will work in the end.
Here is the code from the apache .htaccess file:
RewriteEngine on
Options -MultiViews
RewriteCond %{HTTP_COOKIE} HTTP_IS_RETINA [NC]
RewriteCond %{REQUEST_FILENAME} !#2x
RewriteRule ^(.*)\.(gif|jpg|png)$ $1#2x.$2
# if #2x isn't available fulfill the original request
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)#2x\.(gif|jpg|png)$ $1.$2
I tried to use th URL Rewrite module, but it won't rewrite the URL for some reason. If I go to this website: http://localhost/projectredrum/foto.php it will show the correct page, but it doesn't rewrite the URL to what I want.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
RewriteBase /projectredrum/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foto\.php$ /Aquaria-Foto/Fotos
</IfModule>
Rewrite Module Tutorial
After looking at the tutorial mentioned above I figured I should try without
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Because if you use this, it will only rewrite the URL when the URL doesn't match a file name or directory.
However when I did that I got a 404 page not found issue.
Does anyone know why the URL rewrite doesn't work?
Apache does local rewrite, because page is in same server it can load it on same request. Add [R,L] to end of RewriteRule line to rediret browser to wanted address.
R means temporally Redirect,
L means last rule.
R=301 is permanent redirect
eg [R=301,L] does permanent redirect and stops checking other rules.
In your case, you probably want to use this kind line:
RewriteRule ^foto\.php$ /Aquaria-Foto/Fotos [R,L]
Here is more info about flags: http://httpd.apache.org/docs/2.4/rewrite/flags.html
It is not working because of this condition:
RewriteCond %{REQUEST_FILENAME} !-f
since http://localhost/projectredrum/foto.php is a valid file.
To fix the rule you can use this in /projectredrum/.htaccess:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /projectredrum/
RewriteCond %{THE_REQUEST} /foto\.php[?\s] [NC]
RewriteRule ^ /Aquaria-Foto/Fotos [L,NC,R=302]
R=302 is used to actually redirect the URL in browser.
In DocumentRoot/.htaccess you can use:
RewriteEngine On
RewriteRule ^Aquaria-Foto/Fotos/?$ /projectredrum/foto.php [L,NC]
References:
Apache mod_rewrite Introduction
Apache mod_rewrite Technical Details
Apache mod_rewrite In-Depth Details
How to rewrite /foo-bar to foo-bar.html but /foo/bar to foo--bar.html using mod_rewrite?
In other words, replace all slashes in the request URI with --, then append .html.
I wrote the following code:
RewriteEngine On
RewriteBase /
# Take care of /foo/bar and /foo-foo/bar-bar
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z0-9-]+)/([a-z0-9-]+)/?$ $1--$2.html [L]
# Take care of /foo, or /foo-bar-baz-whatever-no-slashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z0-9-]+)/?$ $1.html [L]
This seems to work on some servers but on mine it seems to mess up the rewrites:
The requested URL /foo.html/bar was not found on this server.
It seems to append the .html too early.
Any ideas on how to fix this, and what is causing it to fail on this particular server?
I'm not sure why your example isn't working. Supplying the apache vesion you are using would help a lot. I was able to replicate the issue with Apache/2.2.14
If you remove the RewriteBase Directive and go with
Apache/2.2.14
RewriteEngine On
# Take care of /foo/bar and /foo-foo/bar-bar
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([a-z0-9-]+)/([a-z0-9-]+)/?$ /$1--$2.html [L]
# Take care of /foo, or /foo-bar-baz-whatever-no-slashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([a-z0-9-]+)/?$ /$1.html [L]
you should have better luck.
In the future look turn up your log level for easier debugging of what's going on.
#don't leave this on in production
RewriteLog "/private/var/log/apache2/rewrite.log"
RewriteLogLevel 5
One case where this seems to happen is when MultiViews is enabled, but AcceptPathInfo is set to Off (or Default and the handler doesn't accept path info), and foo.html exists.
Apache notices that your request for /foo/bar doesn't point to a real resource, and maps it to /foo.html with the path info of /bar. Because path info is not allowed, Apache returns a 404 for the request. Likewise, mod_rewrite doesn't perform a rewrite because /foo.html now is an existing file.
The solution for this scenario would be to turn off MultiViews in your .htaccess file:
Options -MultiViews
Background information:
I've searched stackoverflow for a specific solution and couldn't find one that fixed my situation. Thanks in advance for any help you can offer. Your knowledge is appreciated.
I've decided to accept a contract to "convert" (in the client's words) a Joomla site into a WordPress site. Everything is going along smoothly, except that the Joomla site links to .html files, both in its navigation and in the content of 100+ posts.
Instead of going through each post one-by-one and updating the links or running a SQL command to remove ".html" from URLs, I've decided to put the pressure on .htaccess, with which I am somewhat comfortable.
What I'm trying to do ↓
In WordPress, I have custom permalinks enabled, and it is as follows:
/%category%/%postname%
Here's an example of what one of the old URLs in the posts looks like:
http://the-site.com/category/the-webpage.html
I need the htaccess file to tell the webserver to remove the .html so the user, after visiting "http://the-site.com/the-webpage.html" is instead sent to:
http://the-site.com/category/the-webpage
I'm setting up the page stubs to follow the file name of the Joomla pages, so http://the-site.com/category/the-webpage will work.
My question:
Can you help me discover the solution to removing .html from the URL when someone visits the site, even if the HTML file doesn't exist on the server?
Here's how the .htaccess file looked before I made changes:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Here's the latest .htaccess file as of 5:35pm Eastern:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)\.html$ $1 [R=301,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
The ↑latest .htaccess changes work. Thanks Tim!
This will work to force an external redirection to your new URLs, but this may not be ideal for your situation. I'm still trying to think if there's a way to keep the redirection internal and update the variable that WordPress uses to determine which page to serve up, but so far I haven't thought of anything that would work.
Entire .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)\.html$ $1 [R=301,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
You want to use a URL rewrite
RewriteEngine On
RewriteRule ^(.*)\.html$ $1
This should do it. It will rewrite a request to site.com/category/whatever.html to site.com/category/whatever. it shouldn't be dependent upon the requested file existing.
<Directory /var/www/category>
RewriteEngine on
RewriteRule (.*)\.html$ /category/$1
</Directory>
This is the format for apache2.conf or virtual host files. Not sure if you use the command in .htaccess. It's best to take care of it in the server conf, if you can, as that is only parsed once, on server startup, and htaccess is parsed on each request.
Ok. So I'm building this site which is accessible through two different domains. So I can't use RewriteBase in my .htaccess. The rules (below) I use to work around this problem seem to work fine. However, when I use the below .htaccess settings on my local box with clean URLS (WAMP) it all works fine but the moment I use this on the live server (shared hosting LAMP) every page I navigate to displays the home page (the one under index I guess) even though the URL in the browser is clearly being updated.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/domain1.com/(.*)$
RewriteRule ^(.*)$ /domain1.com/index.php?q=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/domain2.com/(.*)$
RewriteRule ^(.*)$ /domain2.com/index.php?q=$1 [L,QSA]
</IfModule>
Any help or ideas are very much appreciated.
Luke
Probably the best thing to do is to reproduce the problem on your local box and turn up RewriteLogLevel so you can see what's going on. (Since you usually can't change the log level on shared hosting)
You may be able to "simulate" the problem by doing a directory rewrite in your Apache main configuration. (The shared hosting obviously does its own rewriting before it gets to the .htaccess!) If you can't reproduce the problem, you may have to start trial-and-error debugging on the remote server. This is ugly but if it's your only option:
Use the R (redirect) flag in substitutions to send any rewritten URL back to your browser. Use TELNET (or an appropriate browser add-on) to inspect the HTTP responses.
Don't forget to escape dots in regexes!
As a side note, the RewriteRule pattern is matched before the RewriteConds above it. This kind of setup is probably better for performance:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/domain1\.com/(.*)$ /domain1.com/index.php?q=$1 [L,QSA]
# ^ should be escaped
Note that I haven't tested this.