I've recently implemented IIS URL Rewriting on one of my websites. I'm using URL Redirection rather than rewriting for everything. All of my static redirections are working perfectly, however, there's one specific type of dynamic redirection that I can't seem to make work.
I had old URL's that looked like this:
http://example.com/?tag=mytag
I'd like this to be redirected to the new URL format of:
http://example.com/tag/mytag
For these URL's the querystring key (tag) is known and fixed, however, the querystring value ("mytag" in the example above) is entirely dynamic and unknown in advance (so I don't believe it's therefore possible to use IIS Rewrite Maps).
Is is possible to add an IIS Rewrite rule that performs this kind of redirection for all possible querystring values that may be supplied?
Yes, the guts of the solution are below. Whats going on is...
1st condition means only apply this rule to the top level of the site. So http://example.com/?tag=mytag will redirect, whereas http://example.com/foobar/?tag=mytag wouldnt.
2nd condition is the magic. It only runs if a query param called tag exists, and the (.*) is a regex to grab the value for use in the new URL.
The action uses the value you grabbed in the 2nd condition referenced as {C:1}. appendQueryString does exactly what it says - set as appropriate. redirectType should be left as Temporary (HTTP response code 307) until your happy, then change it to Permanent (HTTP response code 301). Once you send a 301 response the client(/search engine) will potentially cache the response and not re-request from the server causing problems if you make a mistake.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect based on tag query value">
<conditions>
<add input="{REQUEST_URI}" pattern="$" />
<add input="{QUERY_STRING}" pattern="tag=(.*)" />
</conditions>
<action type="Redirect" url="tag/{C:1}/" appendQueryString="false" redirectType="Temporary" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Related
I'm trying to map a URL like this:
www.domain.com/some-page.cfm?coid=1
to be more user-friendly like this:
www.domain.com/some-page/company-name
or
www.domain.com/company-name
I've tried over and over using URL Rewrite in IIS and can't for the life of me get it to work.
Any help would be appreciated!
I think you may actually want to do the opposite... use IIS to map /abc.htm requests to /?id=abc, right? (For the rule you are requesting, I recommend writing that using ColdFusion.)
Here's an IIS rule that we use in order to not expose ".cfm" in our blog URLs. Anything URL parameters after "/blog/" in the URL is available to ColdFusion as URL.WebPath. Additional URL parameters are retained. If you modify this, I recommend matching a URL patterns (like "blog/" or "/detail-") so that only specified URLs are rewritten.
<rewrite>
<rules>
<rule name="CFMBlog" patternSyntax="ECMAScript" stopProcessing="true">
<match url="blog/(.*.htm)$" ignoreCase="true" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{SCRIPT_FILENAME}" matchType="IsFile" negate="true" />
<add input="{PATH_INFO}" pattern="^.*(blog/index.cfm/).*$" negate="true" />
</conditions>
<action type="Rewrite" url="/blog/index.cfm?WebPath={R:0}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
On the ColdFusion-side, you'll want to analyze the URL and ensure it's in the proper format. You don't want to have both versions of the URLs responding for fear of SEO duplication (unless you set up URL canonicalization). I'm my experience, it's best to serve a 301 Permanent Redirect to a lowercased, dash-separated ".htm" version of the URL.
In your CFM pages, you'll need to add some logic to check whether .htm is in path_info, URL.COID exists in the original request and URL.webpath does not. Depending on your situation, you could perform a 301 to redirect to the HTM version of the URL so that both search engines & users are aware of the new URL.
Have you taken a look at this? IIS URL Rewrite not working with query string
Or if you want to do this with pure ColdFusion without IIS, how about this?
some-page.cfm
<!--- Test for query string params --->
<cfif StructKeyExists(url, "coid") and url.coid eq 1>
<cflocation url="/some-page/company-name" addtoken="no">
<cfelse>
<!--- Other processing here... --->
</cfif>
I need to redirect a "fake" sub domain to a real subdomain in IIS 7.5. The reason is that the marketing department doesn't want to use the actual website address in print pieces.
Actual site URL:
reporting.usapartners.com
Marketing dept wants
report.usapartners.com (fake) to redirect to reporting.usapartners.com (real)
Again, report.usapartners.com does not exist, only reporting.usapartners.com exists
Here is what I tried
I added a binding in IIS, for the site reporting.usapartners.com. I added report.usapartners.com as the host name and used the reporting.usapartners.com IP address
Then I went into reporting.usapartners.com web.config and added this:
<rewrite>
<rules>
<rule name="report" stopProcessing="true">
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="report.usapartners.com" negate="false" />
</conditions>
<action type="Redirect" url="http://reporting.usapartners.com" appendQueryString="false" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
Looks like my solution creates an alias that cannot be redirected to.
Am I even approaching this problem correctly? Seems like it should be a simple problem to solve but perhaps not? Any ideas are welcomed and appreciated.
Thanks
I think you need to create a separate site with host bindings for report.usapartners.com (the fake site) in IIS. This is going to be a stub site (it will still need a path on the disk, but it's only going to have a web.config in there) which will just host a redirect rule.
Now click on HTTP Redirect for that site in IIS and tick Redirect requests to this destination and put http://reporting.usapartners.com in the textbox. Then tick Redirect all requests to exact destination (instead of relative to destination), don’t tick the next one and then choose Status Code Permanent (301).
If you want it to redirect and keep the subdirectories and/or query string, then you can change the contents of the textbox to be http://reporting.usapartners.com$S$Q. Note that there is no trailing slash in this case. The $S preserves the sub directories and the $Q preserves the query string.
Your rule is causing a redirect loop.
Observe what your rule does:
Match any given URL (this includes "/", "/something", "/something/another.html", etc.)
If the host name ISN'T "report.usapartners.com"
Redirect permanently the request to "http://reporting.usapartners.com"
So, as you see, as soon as the user is redirected to the reporting subdomain, it gets redirected again to reporting, because hostname isn't "report.usapartners.com".
The key here is the negate="true" attribute on the rule condition. Remove it or set it to false and you are good to go.
Edit:
You are almost there.
The real solution would be to change the host name on the rule to the desired host, keeping the negate true, so your rule would do:
Match any given URL (this includes "/", "/something", "/something/another.html", etc.)
If the host name ISN'T "reporting.usapartners.com"
Redirect permanently the request to "http://reporting.usapartners.com"
Code:
...
<add input="{HTTP_HOST}" pattern="reporting.usapartners.com" negate="true" />
...
I have setup a URL rewrite in IIS 7 for a particular site, that has 2 bindings.
main.mydomain.com
hub.mydomain.com
I have also applied a URL Rewrite Rule as shown below:
match (.*)
and then
under the condition
where {HTTP_HOST} matches ^hub\.mydomain\.com$
301 redirect to
http://main.mydomain.com/hub/home.html
and this works, the purpose was to have hub.mydomain.com direct the user to a URI of http://main.mydomain.com/hub/home.html
I have now been asked to change this so that the hub.mydomain.com remains in the user's browser address but that they are shown the correct /hub/home.html content.
How can this be achieved? I presume that as the name suggests, URL Rewrite is no longer suitable? and if so how else can I do this?
EDIT:
main.mydomain.com still needs to go to the root of the website.
In your question, you state that main.mydomain.com and hub.mydomain.com are binded to a single website.
So if you want the users who hit hub.mydomain.com to be shown with the content from http://main.mydomain.com/hub/home.html, it is equivalent to have them hit hub.mydomain.com and be shwon the content from http://hub.mydomain.com/hub/home.html.
You rule would then go as:
<rule name="hub rewrite">
<match url="^/?$" />
<conditions>
<add input="{HTTP_HOST}" pattern="^hub\.mydomain\.com$" />
</conditions>
<action type="Rewrite" url="hub/home.html" />
</rule>
I'm using IIS URL rewriting module to mask my internal URLs with friendly URLs through rewrite maps and Rewrite rules (not redirection). This is my rewrite map:
<rewriteMap name="HashTest">
<add key="/nohash" value="/nohash.aspx" />
<add key="/hash1" value="/hashtest.aspx#hash1" />
</rewriteMap>
and this is my rewrite rule:
<rule name="Rewrite rule1 for HashTest">
<match url=".*" />
<conditions>
<add input="{HashTest:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" />
</rule>
This is working for URLs with no hashtags, so every time I query www.mysite.com/nohash it shows me content from www.mysite.com/nohash.aspx with our changing the URL on the browser.
Now when I try to rewrite to a URL containing a hashtag I get a 404 error, for instance www.mysite.com/hash1 should just show me content from /hashtest.aspx#hash1 but I just get a 404.
Now if I change my rule action type to Redirect it does make redirection successfully, so I don't know why it doesn't work with rewrite.
I know hashtags are not sent to the server on the request, but it would make sense if my rewrite map was backwards, like <add key="/hashtest.aspx#hash1" value="/hash1" />.
Any insights on why redirection works with hastags but rewrite doesn't?. I'm not married to IIS redirection, if you have another module or approach I can use it's very welcome
The part after the hash sign (officially called the fragment identifier) is a client-side only part of the URL. It's never send to the server. That's why it won't work for rewrite but only for redirects. The rewrite rule will match but IIS will actually try to open a file called hashtest.aspx#hash1 (i.e. a file with the extension .asp#hash1). This file won't be processed as a normal ASP page as the extension is not linked to ASP.NET. And most likely it's content won't even be displayed at all as IIS is by default configured to only allow request for known extensions.
I am having a problem with an IIS7 Integrated Pipeline URL Rewrite.
For my particular scenario I need to rewrite/redirect part of the initial request as follows.
User enters http://savecontoso.com/files/123456789/somefile.html in the browser address bar.
User is redirected to http://savecontso.com/default.aspx?url= (results of url="default.aspx?url={R:1}")
This currently works as expected only if I create the initial request as such, http://savecontoso.com/default.aspx/files/123456789/somefile.html.
I must note that there is no actual directory of /files/ nor /123456789/ nor any file named somefile.html on the server. I simply need that entire path and filename appended to a query string.
This is my first day working with redirect/rewrite functions using IIS instead of page code behind and I have looked all around learn.iis.net, Google etc to no avail. I understand that rewriting takes place before page requests but for some reason my particular code requires a page request before firing the redirect.
I suspect it is because I am not triggering conditions at the initial request?
<rewrite>
<rules>
<rule name="1" stopProcessing="true">
<match url="(.*)(/files/\d+/.*html$)" />
<action type="Redirect" redirectType="Permanent" url="default.aspx?url={R:1}" />
</rule>
</rules>
</rewrite>
Most likely it does not work because of your match pattern:
the {R:1} will only match (.*) in your pattern, and will never match files/123...
URL in match pattern always starts with no leading slash: should be files/\d+... and not /files/\d+...
Try this one instead (works fine for me):
<rule name="1" stopProcessing="true">
<match url="^files/\d+/.*\.html$" />
<action type="Redirect" url="default.aspx?url={R:0}" redirectType="Permanent" />
</rule>