How to use htaccess to rewrite url to html anchor tag (#) - .htaccess

I have a situation where I want to take the following URL:
/1/john
and have it redirect using Apache's htaccess file to go to
/page.php?id=1&name=john#john
so that it goes to an html anchor with the name of john.
I've found a lot of reference to escaping special characters, and to adding the [NE] flag so that the redirect ignores the # sign, but these don't work. For example, adding [NE,R] means that the URL just appears in the browser address as the original: http://example.com/page.php?id=1&name=john#john.

This is possible using [NE] flag (noescape).
By default, special characters, such as & and ?, for example, will be converted to their hexcode equivalent. Using the [NE] flag prevents that from happening.
More info http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_ne

You can in fact do one of these things, but not both.
You can use the [NE] flag to signify to Apache not to escape the '#' character, but for the redirect to work, you have to specify an absolute URL to redirect to, not simply a relative page. Apache cannot do the scrolling of the window down to the anchor for you. But the browser will, if you redirect to an absolute URL.

What you want to do, can be accomplished with URL rewriting, or, more specifically, URL beautification.
I just quickly found this well explained blog post for you, I hope it can help you out with the learning to rewrite URLs-part.
As for the #-thing (expecting that you now know what I'm talking about), I don't see a problem in passing the same variable to the rewritten URL twice. Like: (notice the last part of the first line)
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ /$1/$2/#$2 [R]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/$ /index.php?page=$1&subpage=$2
Though, you'll have to escape the #-part, and it seems that it can be done this way:
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ /$1/$2/\%23$2 [R,NE]
BTW, URL rewriting is not that hard (but can become complicated, and I'm not an expert), but Google can help a lot along the way.

You cannot do an internal redirect to an anchor. (Just think about it: how would Apache scroll down to the anchor?) Your link should pointo to /1/john#john. Anchors aren't part of the request uri.

Related

How can I use mod_rewrite and preserve the url's fragment (anchor part)?

I'm taking a site that used to be static html (generated by an offline tool) and converting it to PHP. I'm sending all page urls to a single PHP file which parses the url. At first I just stuck FallbackResource MyPage.php in the .htaccess file, and it worked fine... except for urls with a fragment part. Many of the old urls were like /some-page.html#part2, and in the new scheme, part2 is a whole separate page, so I can't ignore that part of the url. With FallbackResource, all that MyPage.php would ever see is /some-page.html.
Now I've read some other questions on here about the topic, such as this one, and it seemed clear that mod_rewrite should in theory be able to do the job, but I can't get it to work. Here's my most current attempt:
Options +Indexes
DirectoryIndex MyPage.php
RewriteEngine on
#RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[^:/.?#&]+\.html#(\w+) MyPage.php#$1 [NC,NE]
RewriteRule ^[^:/.?#&]+\.(html|php) MyPage.php [NC]
This works, again, for everything except anchors. It works no better than the old FallbackResource command did. I've tried juggling various parts of this in random ways, such as looking for %23 instead of #, omitting the NE flag, passing the value in a querystring instead of as a fragment, and whatnot.
I will note that I don't want to use redirection to translate the urls -- the PHP has to perform a lookup on it.
Well, I guess the answer is that it can't be done. The fragment part is never even sent to the server as part of the HTTP request. It stays inside the browser. Which means if anyone's saved an old link, it's just gonna go to the wrong page and that's all there is to it.
But I can write javascript into the page to redirect from the client. The PHP can iterate through the known list of old anchors on a given page and emit conditions to send them to the new page.

How to redirect only when there is something after .html?

I have found that there are some people with bad syntax links to our articles.
For example, we have an article with URL
http://www.oursite.com/demo/article-179.html
The issue is that lot of people have linked back to this article with bad syntax such as
http://www.oursite.com/demo/article-179.html%5Cohttp:/www.oursite.com/demo/glossary.php
Now, I added the following ReWrite Rule in the .htaccess file to take care of such links.
RewriteRule article-179\.html(.*)$ "http\:\/\/www\.oursite\.com\/demo\/article-179\.html [301,L]
But this has resulted in a Redirect Loop message. How can we fix this issue via htaccess rewrite rule. Basically, we need something in our rewrite rule that works only when there is one or more characters after the .html. If not, then it should not redirect.
Any help would be highly appreciated!
With best regards!
Use + instead of *. * matches zero or more, which causes the pattern to match for the redirected path too, + instead matches one or more.
Also you should make the pattern as precise as possible, ie don't just check whether it ends with article-179.html, better check for the full path. And if this all happens on the same domain, then there's no need to use the absolute URL for the redirect.
There's also no need for escaping the substitution parameter like you did, it's treated as a simple string except for:
back-references ($N) to the RewriteRule pattern
back-references (%N) to the last matched RewriteCond pattern
server-variables as in rule condition test-strings (%{VARNAME})
mapping-function calls (${mapname:key|default})
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule
Long story short, theoretically this should do it:
RewriteRule ^demo/article-179\.html(.+)$ /demo/article-179.html [R=301,L]
or this if you really need the absolute URL:
RewriteRule ^demo/article-179\.html(.+)$ http://www.oursite.com/demo/article-179.html [R=301,L]

special characters in url using htaccess

The idea is to use www.example.com/admin/#!/12345 as www.example.com/admin/user.php?id=12345
This is the rewrite rule Im trying, but this doesn't seem to work
RewriteRule ^admin/#!/(.*) www.example.com/admin/user.php?id=$2
How do I include such special characters ?
Thank you
You can't use # is URLs. The browser will interpret it as a fragment identifier and never even send it (or the following part of the URL) to the server.

Is it possible to handle such URL

http://www.example.com/http://www.test.com
I have tried many different methods using .htaccess with no luck. I need to get that second url coming as parameter. Is it possible to redirect it to index.php and get it as $_SERVER["REQUEST_URI"] or other method? Thanks
UPD: Looks like it is impossible to get whole URL, question marks are not recognized. Ideal example:
127.0.0.1/http://www.test.com/script.php?a=hello&b=world#blabla;par2?%par3
and i need to get in my index.php exact string
www.test.com/script.php?a=hello&b=world#blabla;par2?%par3
It's definitely possible: http://downforeveryoneorjustme.com/http://www.google.com/
As to how, it's been covered on ServerFault already
The Problem:
This is a problem with Apache running on Windows. Apache on Windows does not let you have a colon (:) in your REQUEST URI. This is basically for avoiding URLs like http://www.mysite.com/C:/SomeFile.exe but is actually annoying.
If you use mod_rewrite at the same time it will be skipped.
You and some applications (like wikipedia) uses colon : in URL. so what to do in Apache on Windows?
The Solution:
At the time of writing this answer this bug still persists and there is no absolute solution, BUT there is a trick:
You may change your URL to something like this:
http://www.mysite.com/url/http://www.test.com
in this example http://www.mysite.com/ is your SCRIPT PATH and /url/http://www.test.com is your REQUEST URI.
The problem will be gone if there is a Slash (/) before Colon (:).
You can get the URI but only without the fragment since that is not transmitted to the server. Try this rule:
RewriteRule ^http:/ index.php [L]
Then the requested URI path plus query (so the part from the third / up to the first # or the end of the URI) is available at $_SERVER['REQUEST_URI'].

.htaccess, two consecutive rewrites?

I need to take a url, "/ServiceSearch/r.php?n=blahblah", and have it go to "/search/blahblah/" so that it appears in the browser as "/search/blahblah", but I actually want it to REALLY be going to "r.php?n=ServiceSearch&n=blahblah"..
So I was thinking I'll need to rewrite the first URL to "/ServiceSearch/r.php?n=blahblah" and then the second url, "/search/blahblah/", to the third, "r.php?n=ServiceSearch&n=blahblah".
Well, I know this is wrong, but it's my best guess. I'm really struggling with it.
Well, I know this is wrong
No, that’s actually the right way. Something like the following should work:
RewriteRule /ServiceSearch/r.php?n=(.*)$ /search/$1 [R]
RewriteRule /search/(.*)$ /r.php?n=ServiceSearch&n=$1 [L]
Here, (.*) captures the variable part (“blablabla”) and inserts it into the replacement via $1. The flags at the end mean that the first query should be a HTTP redirect ([R]), i.e. the client’s browser will be instructed to redirect to that address. And that the second redirect is to be the last ([L] – it’s also not an HTTP redirect since we didn’t specify that; instead, the redirect is handled on the server side). Strictly speaking, the [L] flag isn’t necessary but if you later add more rewrite rules it will prevent unwanted interference.

Resources