Search code examples
http-redirectiisurl-rewritingfile-extensionno-www

In IIS, how can I forward all my URLs to a non-www, https, and no file extension without having too many redirects


I have gone through many similar questions in Stack Overflow, but I have not been able to find one that helps me to have all three of these re-direct rules work together.

I am trying to forward all of my URLs to this format:

https://example.com/page

I need the https, I don't want the www, and I don't want the html or aspx extensions to be visible. Here is what I have so far. Chrome says that I have too many redirects, how do I consolidate these rules?

    <rewrite>
        <rules>
            <clear />

            <rule name="RewriteHTML">
                <match url="(.*)" />
                <conditions logicalGrouping="MatchAll">
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                </conditions>
                <action type="Rewrite" url="{R:1}.html" />
            </rule>

            <rule name="Redirect www to non-www" enabled="true" stopProcessing="true">
                <match url="(.*)\.html$" />
                <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                    <add input="{HTTP_HOST}" pattern="^example\.com$" negate="true" />
                </conditions>
                <action type="Redirect" url="http://example.com/{R:1}" redirectType="Permanent"/>
            </rule>

            <rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
                <match url="(.*)\.html$" />
                <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                    <add input="{HTTPS}" pattern="^OFF$" />
                </conditions>
                <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent"/>
            </rule>

            <rule name="RemoveExtension" stopProcessing="true">
                 <match url="(.*)\.html$" />
                 <action type="Redirect" url="{R:1}" redirectType="Permanent" />
            </rule>

        </rules>
    </rewrite>

Solution

  • I finally figured it out after playing around with patterns and rule orders, and the stopProcessing command, etc. No more redirect loops! I actually figured out what I was asking and more.

    1. Removes index.html from root domain
    2. Redirects www to non-www
    3. Removes trailing slashes
    4. Makes the URL always lowercase
    5. Redirects http:// to https://
    6. Enables URL to work without .html extension
    7. Redirects to URL without .html extension

    My code:

    <rules>         
        <!-- index.html Redirect -->    
        <rule name="index.html Redirect" enabled="true">
            <match url="^(.*\/)*index\.html$" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_METHOD}" negate="true" pattern="^POST$" />
            </conditions>
            <action type="Redirect" url="{R:1}" redirectType="Permanent" />
        </rule> 
    
        <!-- Redirect WWW to non-WWW -->
        <rule name="Redirect WWW to non-WWW" enabled="true">
            <match url="(.*)" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="^example\.com$" negate="true" />
            </conditions>
            <action type="Redirect" url="http://example.com/{R:1}" />
        </rule>
    
        <!-- Remove Trailing Slash -->
        <rule name="Remove Trailing Slash" enabled="true">
            <match url="(.*)/$" />
            <conditions>
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            </conditions>
            <action type="Redirect" url="{R:1}" />
        </rule>
    
        <!-- Make URL Lower Case -->
        <rule name="Make URL Lower Case" enabled="true">
            <match url="[A-Z]" ignoreCase="false" />
            <action type="Redirect" url="{ToLower:{URL}}" />
        </rule>
    
        <!-- Redirect To HTTPS -->
        <rule name="Redirect To HTTPS" enabled="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTPS}" pattern="^OFF$" />
            </conditions>
            <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
        </rule>
    
        <!-- Redirect To URL With No Extension -->
        <rule name="Redirect To URL With No Extension" enabled="true">
            <match url="(.*)\.(html)" />
            <action type="Redirect" url="{R:1}" />
        </rule>             
    
        <!-- Rewrite URL For No Extension -->
        <rule name="Rewrite URL For No Extension" enabled="true" stopProcessing="false">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            </conditions>
            <action type="Rewrite" url="{R:0}.html" />
        </rule> 
    </rules>
    

    Here is what the rules look like in the IIS URL Rewrite module:

    URL Rewrite Rule Details