Why Aren't My URL Rewrite Maps Changing the Browser's URL? - mod-rewrite

Environment
IIS Server 8
URL Rewrite Module 2.0 (Version 7.2.2; Microsoft)
Rewrite Maps
Static HTML Files
Background
I want to display a user-friendly URL in the Browser by using URL Rewrite Mapping.
Problem
The Browser's URL bar does not change (ie, it does not switch to the user-friendly URL).
Request
Can you please tell me how to get my URL Rewrite Mapping to actually re-write the browser's URL (to the mapped value)?
Sample Code (Web.Config)
<rule name="RewriteMapping" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{Test:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" appendQueryString="false" />
</rule>
<rewriteMaps>
<rewriteMap name="Test" defaultValue="">
<add key="foo.html" value="This-Is-A-Nice-Page-To-Remember" />
</rewriteMap>
</rewriteMaps>

To "rewrite" new canonical URLs to the underlying file
You have created a rewrite map that internally rewrites the "pretty" requested URL to the underlying URL/file that handles the request. Although you appear to have written the key/value pair the wrong way round. It should be:
<add key="/This-Is-A-Nice-Page-To-Remember" value="/foo.html" />
/This-Is-A-Nice-Page-To-Remember is the "pretty" URL being requested, and /foo.html is the underlying file that the request is rewritten to that actually handles the request.
This is not an external redirect that "changes" the URL in the browser. You need to actually change the URLs in your HTML source. The rewrite map does not do this for you (and neither is it meant to).
The rewrite map as written probably isn't actually doing anything (missing slash prefix), but if it did then it would presumably result in a 404 since This-Is-A-Nice-Page-To-Remember won't be recognised as a valid page.
To "redirect" old URLs to new
However, if you are changing an existing URL structure then you can implement an additional "redirect" rewrite map to externally redirect requests for the "old" URL to the desired "pretty" canonical URL (essentially the reverse of the above). But you must have already changed the URLs in your HTML source before doing so. This "redirect" rewrite map is simply to preserve SEO and to ensure that any inbound links from other sites are not broken. If you don't change the URLs in your HTML source, then users still see (and are able to copy) the "old" (non-canonical) URLs and every time the user clicks a link they will be externally redirected (doubling the requests to your server and slowing the user).
For example, to implement a "redirect" rewrite map from the "old" to "new" (canonical) URL, create an additional rewrite map:
<rules>
<rule name="CorrectOldURLs" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{OldRedirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="https://example.com{C:1}" appendQueryString="False" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="OldRedirects">
<add key="/foo.html" value="/This-Is-A-Nice-Page-To-Remember" />
</rewriteMap>
</rewriteMaps>
If this is a new site, then this "redirect" rewrite map is not strictly necessary, since the underlying files should never be exposed.
In Summary
Bringing the above two together, we have:
<rules>
<rule name="RewriteMapping" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{Test:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" appendQueryString="false" />
</rule>
<rule name="CorrectOldURLs" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{OldRedirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="https://example.com{C:1}" appendQueryString="False" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="Test" defaultValue="">
<add key="/This-Is-A-Nice-Page-To-Remember" value="/foo.html" />
</rewriteMap>
<rewriteMap name="OldRedirects">
<add key="/foo.html" value="/This-Is-A-Nice-Page-To-Remember" />
</rewriteMap>
</rewriteMaps>
But to emphasise again, as stated above, you must have manually changed the URLs in the HTML source before implementing this. There is no shortcut here.
Reference:
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-rewrite-maps-in-url-rewrite-module

Related

How do you coordinate redirects between a mobile and full website?

I have a full website and recently added a mobile website. The first thing I did was to redirect calls to the full website from mobile devices to the mobile website. My web.config rules are as follows:
<rewrite>
<rules>
<clear />
<rule name="RequestBlockingRule2" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="false">
<add input="{HTTP_USER_AGENT}" pattern="ipad" />
<add input="{QUERY_STRING}" pattern="mobi" />
</conditions>
<action type="None" />
</rule>
<rule name="RequestBlockingRule1" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_USER_AGENT}" pattern="midp|mobile|phone|android|iphone" />
</conditions>
<action type="Redirect" url="http://www.wkmclaughlin.mobi" />
</rule>
</rules>
</rewrite>
RequestBlockingRule1 looks for a mobile device in the HTTP_USER_AGENT portion of the request and redirects the request to the mobile website if it finds one; RequestBlockingRule2 intercepts requests from iPad devices and requests with “mobi” in the QUERY_STRING to prevent the redirection from occurring.
The problem is that I need to make calls to the full website from the mobile website and cannot do it with these redirects in place. I thought URL Rewrite was only for remote calls to the website, but it seems to process local requests as well. First, it can’t find AC_RunActiveContent.js; when the screen finally forms, all the graphics are gone and the remaining hyperlinks don’t do anything.
But if I temporarily remove the two rules, the full website displays properly. CAN you be routing mobile devices to your mobile website AND display your full website via your mobile site where people are using mobile devices? If so, what changes are needed in the rewrite rules?

Why is IIS 8.5 URL Rewrite throwing a 404 error?

We have modified our file structure a bit since we've found an issue with the result in my other thread and we now we're back where we've started. I have checked out this thread but there is no answer to that question either.
We want the URL to show: https://devbox.mysite.com/kb/article/test-article-1 on the browser.
Below is my URL Rewrite:
<rule name="Article-rewrite" enabled="true">
<match url=".com/kb/article/(.*)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="https://devbox.mysite.com/kb/article/?artID={R:1}" appendQueryString="false" />
</rule>
I have enabled Failed Request Tracing to trace rewrite rules on the IIS but when I added the rules I do not see the Rewrite as an option even though this instruction showed that it's there. This is my settings and it's not showing option. Anyway, this is just a side issue to diagnose my url rewrite issue.
Okay, so I finally figured out the answer to my question. The match URL will match the folder kb/artitcle/ and the a-ZA-Z- will only allow word and dash. In my situation, there will only be one parameter being passed so I intentionally ignoring the ampersand character because in CommonSpot CMS it adds a &cs_pgIsInLView=1 to the end of the URL which causes the rewrite rule to break. So by ignoring this ampersand, it works in my situation. The query_string pattern 1 will ignore rewrite when I tried to login to the page with the url https://devbox.mysite.com/index.cfm?login=1. I'm guess there may be other better ways than this one but for now, this will have to do.
<rule name="Article-rewrite" enabled="true">
<match url="^kb/article/([a-zA-Z\-]+)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="1" negate="true" />
</conditions>
<action type="Rewrite" url="kb/article/?artID={R:1}" appendQueryString="false" />
</rule>

IIS URLRewrite dynamic rule

I am trying to write an IIS URLRewrite rule that could be used dynamically using server variables instead of hard-coding. I tried several variables but can't seem to get to work.
I have a rule http://domain.com/myweb/appname/ that rewrites to http://myweb.com/appname/ which is hard-coded currently. I am hoping to have myweb and appname to be dynamic so I don't have to create a separate rule for each website and apps that I rewrite. Any help would be much appreciated.
<rule name="Inbound URL">
<match url="appname/(.*)" />
<action type="Rewrite" url="http://myweb.com/appname/{R:1}" logRewrittenUrl="true" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
A little bit late, but still.. If you're after rewriting http://domain.com/xxxx/yyyy/zzzz?qqqq to http://xxxx.com/yyyy/zzzz?qqqq then it should be something like this:
<rule name="Inbound URL">
<match url="^([\da-z\.-]+)/([\/\w \.-]+)" ignoreCase="true" />
<action type="Rewrite" url="http://{R:1}.com/{R:2}" appendQueryString="true" />
</rule>
Note that ([\da-z.-]+) is meant to match only valid domain name characters. Path expression ([/\w .-]+) doesn't describe all allowed symbols, but you can always tweak it as you need.

Url rewrite for outbound rules causing infinite redirect on Windows Server 2012 / IIS 8

I have a Windows Server 2012 instance running IIS 8.
We are hosting a .NET 4.0 website trying to use an outbound rewrite rule to fetch CDN assets.
The presence of the outboundRules tag in the web.config seems to throw the site into an endless redirect loop. The site performs perfectly without the outboundRules tag. I have included the actual rewrite rule we are using but even including the outboundRules tag with nothing in it can cause the site to end up non responsive.
We have confirmed that static compression is not enabled for the site which is what a few other posts around the web have referenced but that does not seem to resolve our situation.
<outboundRules>
<preConditions>
<preCondition name="ExcludeAXD">
<add input="{URL}" pattern=".axd" negate="true" />
<add input="{URL}" pattern=".asmx" negate="true" />
<add input="{URL}" pattern=".ashx" negate="true" />
</preCondition>
</preConditions>
<rule name="CDNRule" enabled="true" preCondition="ExcludeAXD"
stopProcessing="true">
<match filterByTags="Img, Input, Script, Link"
pattern="(^.*?(?=/mymediafoldercontainingassets))(.*)" />
<action type="Rewrite" value="{R:1}http://subdomain.mycdn.com{R:2}" />
</rule>
</outboundRules>
Any help would be greatly appreciated,

IIS URL rewriting to redirect querystring addresses to MVC style path to preserve old links

I am trying to preserve old links such as index.php?pageid=123 to the now current /accounts/home. No part of the original URL has to be included in the redirect.
I have a big list of old page links and their new address. I thought it would be really simple to say index.php?pageid=123 = /accounts/home but I can't see how to do it. Most of the examples I see are the other way around whereby your site uses query string and you want your URLs to be SEO friendly. I'm using IIS 7.5 to rewrite.
Thanks
Got it sorted and it wasn't that hard really. Just needed to add the query string as a condition.
<rules>
<rule name="accounting" patternSyntax="Wildcard" stopProcessing="true">
<match url="index1.php" />
<conditions>
<add input="{QUERY_STRING}" pattern="page=accounts/accountsmain" />
</conditions>
<action type="Redirect" url="business-services/accounting.aspx" appendQueryString="false" />
</rule>
</rules>

Resources