Mask URL rewrite in htaccess - apache

I have a wordpress website in project and I want to mask the URL of all the pages so that when accessing them:
https://myweb.com/survey/page1
https://myweb.com/survey/page2
....
is displayed as:
https://myweb.com/survey/portal
I have this on .htaccess but it doesn't work:
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /survey/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /survey/index.php [L]
RewriteRule ^survey/?$ /survey/portal/
Thank you all for your time.

Very nice efforts first of all, could you please try following; written based on your shown samples. Please clear your browser cache before testing your URLs.
Also please your .htaccess file just one level above survey folder.
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /survey/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://%{HTTP_HOST}/portal [R=301]
RewriteRule ^ survey/index.php [L]

There is a common misconception that rewrite rules make ugly URLs pretty; it is more correct to say that they make externally pretty URLs internally ugly.
That's because when the browser sends a request to the web server, the web server can decide what response to serve, but it can't change what the browser sent - that's already happened.
So if you type https://myweb.com/survey/portal into a web browser, the URL sent to the server at myweb.com will be /survey/portal. Your rewrite rules decide what to do when receiving that URL, so your rule might look like this:
RewriteRule ^survey/portal$ survey/index.php
On the left is the URL the browser sent; on the right is what to serve. But notice that it wouldn't make sense to write this:
RewriteRule ^survey/portal$ survey/page1.php
RewriteRule ^survey/portal$ survey/page2.php
RewriteRule ^survey/portal$ survey/page3.php
These all match the same URL, and that URL is all we have to go on, so there is no way to map one URL to multiple pages using this mechanism. You would need something somewhere else to know which page of the survey the user is on.
You can of course do the opposite - match multiple URLs in the browser to the same resource internally:
RewriteRule ^survey/page1$ survey/index.php
RewriteRule ^survey/page2$ survey/index.php
RewriteRule ^survey/page3$ survey/index.php
Or you can map them to slightly different resources:
RewriteRule ^survey/page1$ survey/index.php?page=1
RewriteRule ^survey/page2$ survey/index.php?page=2
RewriteRule ^survey/page3$ survey/index.php?page=3
And you can use patterns and placeholders to avoid having to list out all the possibilities, so that last example can be shortened to:
RewriteRule ^survey/page([1-3])$ survey/index.php?page=$1

Related

htaccess - pretty url with multiple variables

sky
something, 9, anything are variables
in address bar I want to see this:
...host/something/9/anything
so - without sky.php at all
reverse rule - from pretty to ugly - is solved - but if you have any notice - pls do:
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /sky.php?c=$1&id=$2&s=$3 [L]
With your shown samples, please try following. This considers that you want to hit URL like: http://localhost:80/sky.php?c=something&id=9&s=anything in browser which should be redirected to http://localhost:80/something/9/anything here.
Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##This rule handles to change from non-friendly URL to friendly URL in browser.
RewriteCond %{THE_REQUEST} \s/(?:[^.]*)\.php\?c=([^&]*)&id=([^&]*)&s=([^\s&]*) [NC]
RewriteRule ^ /%1/%2/%3? [R=301,L]
##This rule internally rewrites friendly url to non-friendly url.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/?$ sky.php?c=$1&id=$2&s=$3 [L]

htaccess redirect phpbb to subdirectory

I need help with a redirect using htaccess since I moved my phpbb forum to a subfolder called "forum". So I want viewtopic.php?... to redirect to /forum/viewtopic.php?...
and viewforum.php?... to /forum/viewforum.php?...
I google all day and couldn't find an exact code to use so I tried to fiddle with the code to no avail.
RewriteCond %{REQUEST_URI} !forum/
RewriteRule ^([view(.+)\.php(.+)])$ forum/$1 [QSA,NC,L,R=301]
I tried to catch both "viewtopic" and "viewforum" and then redirect it to /forum/ but it's not working.
This should work for you:
RewriteCond %{REQUEST_URI} !^/forum/
RewriteRule ^view(.+)\.php$ /forum/$0 [QSA,NC,L,R]
Because of the nature of the redirect (with the need to capture the entire request URI), there is no need to wrap it - you can just us $0.
You were using square brackets in your capture, which which would not have helped in any way. Square brackets indicate a character set.
If the new rule works for you, change the R flag to R=301 (as you had it previously), which will make the redirect permanent.
Update: Your entire .htaccess file should look like this now:
Options All -Indexes
RewriteEngine On
RewriteRule ^$ - [E=noabort:1]
# Redirect Forum
RewriteCond %{REQUEST_URI} !^/forum/
RewriteRule ^view(.+)\.php$ /forum/$0 [QSA,NC,L,R]
# WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
The redirect rule must come before the WordPress rules.

htaccess rewrite .html not required / is optional

I have a working website, with atleast 500 pages ranked in Google.
All pages have .html at end of page.
Now I want to remove .html of all pages, but let the pages in Google (with .html) keep there index.
After searching I cant find the correct answer.
I know the ? is for optional. I tried 2 Rules behind eachother but didnt work too.
Here is what my htaccess now is:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*).html$ find_page.php?redirect=$1&%{QUERY_STRING} [L,QSA]
I tried with adding:
RewriteRule ^(.*)$ find_page.php?redirect=$1&%{QUERY_STRING}
So if URL contains no extension use this rule, else use the normal rule (with htaccess)
I should expect my rule should be something like this: ^(.*)(?\.html)$
So my goal is: With or without html should work, but .php shouldnt be work :-)
Why look for a complex solution?
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)\.html$ find_page.php?redirect=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)?$ find_page.php?redirect=$1 [L,QSA]
This rewrites all request to that php script, adding the original "file name" as parameter "redirect" and preserves all query parameters. That is what you asked for in your question.
But a warning: you can do this and it will allow to rewrite requests to for example page "redirection" as .../redirection?somearg or .../redirection.html?somearg. But for google both request are completely different pages. This will not help you to preserve any ratings when shifting to the new request scheme.
And a general side note: if you have control over the http server configuration, then you should always prefer to place such rules in the hosts configuration instead of using .htaccess style files. Such files are notoriously error prone, make things complex, are hard to debug and really slow the server down. They should only be used in two cases: if you do not have control over the http server configuration or if you require your scripts to do dynamic changes to your ruleset (which is always a very insecure thing).
Ok solved my problem.
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/]+/)*[^.#?\ ]+\.html([#?][^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.html find_page.php?redirect=$1&%{QUERY_STRING} [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ find_page.php?redirect=$1&%{QUERY_STRING} [L,QSA]
With this option there will be checked if the page has .html optional at end. If it has, will the first rule be matched, else will go further and use the second rule which has no html at the end
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ $1.html
You don't need find_page.php for redirection. As it mentioned in other answer http://server/folder/file and http://server/folder/file.html becomes the same for the user but different for the Google.
This does not affect to PHP, folders and other content. It just tries to add «.html» to requested URL if it does not point a file or folder.
I've checked, it works fine even user queries uri with anchor like 1.html#bookmark1

.htaccess Get requests in the URI

I don't know how I would word this, and I can't make sense of the docs for httpd so I was wondering if anyone knew how to do this.
I would like to get
www.example.com/v/12345/yadayada.png
to actually go to
www.example.com/view?key=12345&img=yadayada.png
I've seen this done some websites but I cant find out how to do this.
Thanks
Edit 1:
I tried this, and then entered the following URL:
www.example.com/v/3f210a2c76cb100f4f7fbd7691a9eb967cb7a1a7/10b78802581bfd59f3fe2b447575bdf7.png
When I did this I got the following error:
The requested URL /v/3f210a2c76cb100f4f7fbd7691a9eb967cb7a1a7/10b78802581bfd59f3fe2b447575bdf7.png was not found on this server.
This is my current .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^./]+\.png)$ /i/$1 [L,NC]
RewriteRule ^v/([0-9]+)/([^/.]+\.(png|jpe?g|gif))$ /view.php?k=$1&img=$2 [L]
#JonLin had the right rule, but the rewrite rule you have declared before that one,
RewriteRule ^([^./]+\.png)$ /i/$1 [L,NC]
is applied to the example url you provided. So, with a request like
www.example.com/v/3f210/10b7.png
would get rewritten to
www.example.com/i/v/3f210/10b7.png
It's worth noting the Flags used for your rules
L - Stop the rewriting process immediately and don't apply any more rules
NC - Makes the pattern comparison case-insensitive.
If you were to remove that rule you would get the results you want. You should also determine if that rule is needed and modify it, the flags, and/or rearrange the order of your rules.
RewriteEngine On
RewriteRule ^v/([0-9]+)/([^/.]+\.(png|jpe?g|gif))$ /view.php?k=$1&img=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Try these rules in the htaccess file in your document root:
RewriteEngine On
RewriteRule ^v/([0-9a-f]+)/([^/.]+\.(png|jpe?g|gif))$ /view?key=$1&img=$2 [L]

Can't get mod_rewrite to correctly (and invisibly) re-write my URLs?

I'm trying to make a URL shortening service for my website.
So instead of:
http://www.myfullwebsitename.com/page78/this-is-a-headline/
users will be able to visit:
http://abc.de/aBxf
which needs to redirect (invisibly!) to
http://abc.de/?shorturl=aBxf
which then 301 redirects via a database lookup to
http://www.myfullwebsitename.com/page78/this-is-a-headline/
I can do the DB lookup and the 301 redirect easily. It's the invisible intermediate redirect that I'm struggling with.
I've tried a LOT of different things, but none seems to work. This is what I currently feel should work:
RewriteCond %{HTTP_HOST} ^abc.de
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/(.+) /?shorturl=$1
But instead of redirecting silently to
http://abc.de/?shorturl=aBxF
it redirects "noisily" (302) to
http://abc.de/aBxF/?shorturl=aBxF
What am I doing wrong?
Thank you!
There's a few things you can try.
I think your RewriteRule should look like this (without the forward /):
RewriteRule ^/(.+) ?shorturl=$1 [L]
This should at the very least stop it from redirecting to http://abc.de/aBxF/.
Your original rule may work if you add:
RewriteBase /
If it were me my rules would actually look like this:
RewriteBase /
RewriteCond %{HTTP_HOST} ^abc.de$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /redirect.php [L]
And then in PHP I would use $_SERVER['REQUEST_URI'] to get the URL (not sure what language you're using).
The rule can look like this:
RewriteRule ^(.*)$ /redirect.php?shorturl=$1 [L]
But I would make sure to mention the script by name. Part of what may be throwing your rules off is relying on Apache finding your index file after a rewrite.
The way Apache's rewrite rules work is as soon as the URL is rewritten, it actually will re-run the rules until no other rules will be found. The [L] flag for "last" says "stop here" - but it still starts over from the top. The RewriteCond with the !-f flag says "only if the file doesn't exist".
Use an absolute URL:
RewriteCond %{HTTP_HOST} ^abc.de
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*)$ http://abc.de/?shorturl=$1 [R=301,L]