Need to rewrite URL contain # tag in htaccess - .htaccess

I need to rewrite URL in .htaccess? Here below is a description of my problem.
URL: www.example.com/about.php#vision
Needs to be rewritten as: www.example.com/vison.html
I tried this as mentioned in below, but it does not work
RewriteRule ^vison.html$ about.php#vision [L]
RewriteRule ^our-vision.html(.*)$ about.php$1 [L,NC]

The short answer is: it is not at all possible using .htaccess!
A longer answer:
The part after the # character is not sent from the browser to the web server, as it is only used client-side.
That type of "rewriting" must take place using client-side JavaScript.
The hashchange event might be a starting-point for you:
window.addEventListener('hashchange', function() {
var hash = location.hash.substr(1);
window.location.href = "/" + hash + ".html";
});
You should also look up SPAs (single page applications). There are lots of frameworks that will help you build solutions like these. Also, there are much more modern techniques that don't rely on hashes, like the popstate event and the mechanisms surrounding it.
A couple of frameworks that could help you get started:
AngularJS
Ionic
Update
When looking at your current .htaccess setup, it looks as if you want to do the reverse of what your question text implies - when someone requests the vison.html, you want to redirect them to about.php#vision - and not the other way around.
If that is true, then yes, you can do it using .htaccess by adding the R flag (REDIRECT) and also the NE flag (NO ESCAPE) to prevent the # character from being encoded:
RewriteRule ^vison.html$ about.php#vision [NE,R,L]

Related

htaccess redirect not working for long url

How do I redirect the following long link:
http://www.vbpmonitor.com/index.php?option=com_content&view=article&id=24&utm_source=MagnetMail&utm_medium=email&utm_term=asmith#panaceainc.com&utm_content=EVVWP040716&utm_campaign=White%20Paper%3A%20Optimizing%20VBM%20Quality%20Tiering%20for%20Physicians
to
http://www.vbpmonitor.com/optimizing-vbm-quality-tiering-for-physicians
Redirect 301 /index.php?option=com_content&view=article&id=24&utm_source=MagnetMail&utm_medium=email&utm_term=asmith#panaceainc.com&utm_content=EVVWP040716&utm_campaign=White%20Paper%3A%20Optimizing%20VBM%20Quality%20Tiering%20for%20Physicians http://www.vbpmonitor.com/optimizing-vbm-quality-tiering-for-physicians
As said above in the comments I suspect that you have a glitch in your logic here and that in reality you want to redirection to work the other way 'round. Redirecting from the long to the search engine friendly URL simply does not make any sense. So:
Using a Redirect rule you could try that instead:
Redirect 301 /optimizing-vbm-quality-tiering-for-physicians /index.php?option=com_content&view=article&id=24&utm_source=MagnetMail&utm_medium=email&utm_term=asmith#panaceainc.com&utm_content=EVVWP040716&utm_campaign=White%20Paper%3A%20Optimizing%20VBM%20Quality%20Tiering%20for%20Physicians
This will redirect an incoming request to the short URL to the actually existing long URL. That is the usual scenario.
If however you really want to redirect that short URL to the long version, then you cannot do that with a Redirect rule. This might for example be the case if you accidentally sent out that long URL and have a working redirection setup for the short version. Unfortunately you do not explain anything about that in your question or comments, so I can only guess here.
You'd have to use the more flexible rewriting module and use a combination of RewriteCond and RewriteRule. That allows to "cut out" specific patterns of request URLs and to "redesign" how the request should look like after the rewriting.
This would be a simple example that applies two conditions to rewriting the request for file index.php to the long URL:
RewriteEngine on
RewriteCond %{QUERY_STRING} view=article
RewriteCond %{QUERY_STRING} id=24
RewriteRule ^/?index\.php$ /optimizing-vbm-quality-tiering-for-physicians [L,R=301]
Note: this version should work both in the http servers host configuration and also in those .htaccess style files. Where you always should prefer the first option if you have access.
As said above, I can only guess here with the sparse information you provided. I picked two out of many request arguments, since those appear to be the ones best suited as distinct identifiers. But you may have to tweak things. Note that per default RewriteConds are combined by a logical AND, so they both have to resolve to something truish.
For more precise details about this stuff I would like to point you to the official documentation of those modules again. The documentation is extremely precise, well written and comes with good examples. I would always prefer the information there to snippets you find somewhere in the internet or partial answers to questions...
http://httpd.apache.org/docs/current/mod/mod_alias.html#redirect
http://httpd.apache.org/docs/current/mod/mod_rewrite.html

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.

.htaccess URL rewrite issue

I've run into a problem when trying to rewrite a url that has a # in it. The rewrite itself is simple:
RewriteRule ^accessories/access/Roll-Up-PR30/accessories.php#a485$ /alog/roll-up-product.php
But it just falls over and will not let me have the hash in there.
Any feedback is welcome as I am running out of ideas :S
Unfortunately most browsers (that I know of) don't send the fragment part of the URL to the server so it's not available in .htaccess; it's just a client-side anchor lookup.
It seems that hashes are a special case. See http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
The relevant section is "Extended Redirection"
RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \
[T=application/x-httpd-cgi,L]

.htaccess mod_rewrite variables through redirect

Short Version:
I wrote the question, and realized most people wouldn't want to read that much text. Consider the below reference, here's the TL;DR:
I need to 301 redirect this url http://app.com/search/foo-bar/
to this url http://app.com/#!/search/foo-bar/
and send this: /foo-bar/, or anything else past /search/ to a server side script. In this case, it's written in php.
Edit for clarity:
Current answers seem to focus on the rewrite to hashbang. That part is not the problem. The problem is that I lose any associated data when rewriting to a hashbang url, as the server side will see app.php as the location, not app.php/#!/foo-bar/ - So I need to capture foo-bar, and send it to the server somewhere other than in the URL. The rewrite works, and is not the issue. Thanks for your answers though!
Long Version:
Ok, so I have an interesting issue that has been tough for me to figure out.
The Scenario:
I have a backbone.js app that uses the hashbang for state:
app.com/#!/search/search-term/key-value/foo-bar/
In addition, I have google traffic coming to the site from the previous version that will be hitting "pretty url" style urls:
app.com/search/search-term/key-value/foo-bar/
I use an .htaccess mod_rewrite to swap the old url out for a hashbanged one if a user hits the legacy url.
I recently introduced a javascript-less bootstrapped version of the site that the site will be built on top of to gracefully downgrade and support crawlers. This is written using php.
For the php site to work, I need to pass in the values past the hashbang to the server side script, so I can figure out what to display.
The Problem:
When I transform a url and add an anchor, everything past the anchor (hashbang) is no longer sent to the request, so I don't have access to it in php.
RewriteRule search/?(.*) #!/search/$1 [R=301,NC,L]
My options for sending things to the server side then are reduced to:
1. Query String
2. Environment Variables
3. Headers
So, I tried sending things via the query string
RewriteRule search/?(.*) #!/search/$1?filter=$1 [R=301,NC,L]
Obviously that didn't work (the query is behind the anchor), so I tried it in front of the hashbang
RewriteRule search/?(.*) ?filter=$1/#!/search/$1 [R=301,NC,L]
That works, but is hideous and redundant to the end user. So, I thought I might try using environment variables.
RewriteRule search/?(.*) /!#/search/$1 [R=301,NC,L,E=FILTER:$1]
That failed, because environment variables aren't preserved through a redirect (duh). I turned to using headers:
RewriteRule search/?(.*) /#!/search/$1 [R=301,NC,L,E=FILTER:$1]
Header set filterParams "%{FILTER}e"
But for some reason, the headers aren't received by the page through the redirect. That seemed to make sense (although I've now stepped well outside of my comfort level with apache directives), so I tried echoing the header, in hopes that it would be passed, received by the second rewrite (that didn't find search), and echoed out.
RewriteRule search/?(.*) /#!/search/$1 [R=301,NC,L,E=FILTER:$1]
Header set filterParams "%{FILTER}e"
Header echo filterParams
Nada - the filter doesn't exist, so although it makes it to the server, it is null. My next thought was to attempt to employ some sort of conditional. Here was my attempt:
RewriteRule search/?(.*) legacy.php/#!/search/$1 [R=301,NC,L,E=FILTER$1]`
<FilesMatch "legacy.php">
Header set filterParams "%{FILTER}e"
</FilesMatch>
Header echo filterParams
That didn't seem to work either, so I'm stumped. I realize that I've spent so long on this that I probably have the solution within my grasp and I'm just tired of looking at it, or it's not even remotely possible, even with gross header hacking.
Anyone have a clue how to to this?
rfc1738.txt says # is not a valid url character
additionally the apache docs says # signals a comment in apache config files.
short answer is your solution is broken not your implementation
AFAIK, there's no good way to preserve variables through redirect without sticking them in the query string...

Getting "mywebsite.org/" to resolve to "mywebsite.org/index.php"

At my work we have various web pages that, my boss feels, are being ranked lower than they should be because "mywebsite.org/category/" looks like a different URL to search engines than "mywebsite.org/category/index.php" does, even though they show the same file. I don't think it works this way but he's convinced. Maybe I'm wrong though. I have two questions:
How do i make it so that it will say "index.php" in the address bar of all subcategories?
Is this really how pagerank works?
Besides changing all the links everywhere, a simpler solution is to use a rewrite rule. Make sure it is a permanent redirect, or Google will keep using the old link (without index.php). How you do this exactly depends on your web server, but for Apache HTTPd it looks something like the example given below.
Yes. Or so I've heard. Very few people know for sure. But Google mentions this guideline (as "Be consistent"). Make sure to check out all of Google's Webmaster guidelines.
Apache config for rewrite rule:
# in the generic config
LoadModule rewrite_module modules/mod_rewrite.so
# in your virutal host
RewriteEngine On
# redirect everything that ends in a slash to the same, but with index.php added
RewriteRule ^(.*)/$ $1/index.php [R=301,L]
# or the other way around, as suggested
# RewriteRule ^(.*)/index.php$ $1/ [R=301,L]
Adding this code to the top of every page should also work:
<?php
if (substr($_SERVER['REQUEST_URI'], -1) == '/') {
$new_request_uri = $_SERVER['REQUEST_URI'].'index.php';
header('HTTP/1.1 301 Moved Permanently');
header('Location: '.$new_request_uri);
exit;
}
?>
You don't tell us if you're using straight PHP or some other framework, but for PHP, probably you just need to change all the links on your site to "mywebsite.org/category/index.php".
I think it's possible that this does affect your search engine rank. However, you would be better off using only "mywebsite.org/category" rather than adding "index.php" to each one.
Bottom line is that you need to make sure all your links in your website use one or the other. What actually gets shown in the address bar is unimportant.
A simple solution is to put in the <head> tag:
<link rel="canonical" href="http://mywebsite.org/category/" />
Then, no matter which page the search engine ends up on, it will know it is simply a different view of /category/
And for your second question--yes, it can affect your results, if Google thinks you are spamming. If it wasn't, they wouldn't have added support for rel="canonical". Although I wouldn't be surprised if they treat somedir/index.* the same as somedir/
I'm not sure if /category/ and /category/index.php are considered two urls for seo, but there is a good chance that it will effect them, one way or another. There is nothing wrong with making a quick change just to be sure.
A few thoughts:
URLs
Rather than adding /index.php, you will be better off making it so there is no index.php on any of them, since the keyword 'index' is probably not what you want.
You can make a script that will check if the URL of the current page ends in index.php and remove it, then forward to the resulting URL.
For example, on one of my sites, I require the 'www.' for my domain (www.domain.com and domain.com are considered two URLs for search purposes, though not always), so I have a script that checks each page and if there is no www., it ads it, and forwards.
if (APPLICATION_LIVE) {
if ( (strtolower($_SERVER["HTTP_HOST"]) != "www.domain.com") ) {
header("HTTP/1.1 301 Moved Permanently"); // Recognized by search engines and may count the link toward the correct URL...
header("Location: " . 'www.domain.com/'.$_SERVER["REQUEST_URI"] );
exit();
}
}
You could mode that to do what you need.
That way, if a crawler visits the wrong URL, it will be notified that it was replaced with the correct URL. If a person visits the wrong URL, they will be forwarded to the correct URL (most won't notice), and then if they copy the url from the browser to send someone or link to that page, they will end up linking to the correct url for that page.
LINKING URLS
They way other pages link to your pages is more important for seo. Make sure all your in-site links use the proper URL (without /index.php), and that if you have a 'link to this page' feature, it doesn't include the /index.php part. You can't control how everyone links to you, but you can take some control over it, like with the script in item 1.
URL ROUTING
You may also want to consider using some sort of framework or stand-alone URL rerouting scheme. It could make it so there were more keywords, etc.
See here for an example: http://docs.kohanaphp.com/general/routing
I agree with everyone who's saying to ditch the index.php. Please don't force your visitor to type index.php if not typing it could get them the same result.
You didn't say if you're on an IIS or Apache server.
IIS can be set to assume index.php is the default page so that http:// mywebsite.org/ will resolve correctly without including index.php.
I would say that if you want to include the default page and force your users to type the page name in the url, make the page name meaningful to a search engine and to your visitors.
Example:
http://mywebsite.org/teaching-web-scripting.php
is far more descriptive and beneficial for SEO rankings than just
http://mywebsite.org/index.php
Might want to take a look at robots.txt files? Not quite the best solution, but you should be able to implement something workable with them...

Resources