Exclude path from RewriteRule using RewriteCond in Apache2

6,962

The exemplified code in your question looks OK in itself, providing:

  • You do not have an OR flag on the preceding condition that would make the next condition (that excludes the specific URL-path) optional.

  • These directives are sufficiently early in your config so as to avoid conflicts with other mod_rewrite directives. Note that the REQUEST_URI server variable is updated in-place if you have earlier directives that rewrite the URL.

  • There are no conflicting mod_alias Redirect or RedirectMatch directives that are overriding these mod_rewrite directives. Note that the order does not matter; the mod_alias directives will execute regardless.

RewriteCond <condition 1>
RewriteCond <condition 2>
RewriteCond %{REQUEST_URI} !^/norewrite
RewriteRule ^.*$ https://example.com [L]

Note that by specifying an absolute URL (scheme + hostname) in the RewriteRule substitution this will implicitly trigger a 302 (temporary) external redirect, not a "rewrite" as you seem to imply. If this should be a "redirect", then you should be explicit and include the R flag - more readable and avoids potential bugs going forward.

Minor point, but you are also missing the trailing slash on the end of the absolute URL (substitution string). If you omit it then you are reliant on the user-agent appending the slash in the redirected request (all major browsers should do this).

If you only want to exclude a single URL-path then you don't need a separate condition. And since you are not currently doing anything with the RewriteRule pattern, it is more efficient to perform this check in the RewriteRule instead.

For example:

RewriteCond <condition 1>
RewriteCond <condition 2>
RewriteRule !^/?norewrite https://example.com/ [R=302,L]

NB: The last RewriteCond should never have an OR flag, otherwise the rule will execute unconditionally. (It's essentially treated like ... OR true.)

The RewriteRule pattern is processed first, so the above states that for all URL-paths that do not start /norewrite then <condtion1>, <condition2>, apply substitution.

Share:
6,962

Related videos on Youtube

Madoc Comadrin
Author by

Madoc Comadrin

Updated on September 18, 2022

Comments

  • Madoc Comadrin
    Madoc Comadrin almost 2 years

    I have Apache server version 2.4.18 (Ubuntu).

    I have conditional RewriteRule that applies to most parts of my site. I want to exclude paths starting with /norewrite from that rewrite.

    The rewrite looks like this:

    RewriteCond <condition 1>
    RewriteCond <condition 2>
    RewriteRule ^.*$ https://example.com [L]
    

    I tried to exclude /norewrite with following:

    RewriteCond <condition 1>
    RewriteCond <condition 2>
    RewriteCond %{REQUEST_URI} !^/norewrite
    RewriteRule ^.*$ https://example.com [L]
    

    I have also tried different syntaxes such as !/norewrite, !norewrite and !^\/norewrite but with all these the addresses starting with /norewrite still get rewriten when the 2 other conditions are true.

    After reading Apache docs for RewriteCond and RewriteRule I belive that this should work. What am I doing wrong here?

    • MrWhite
      MrWhite about 5 years
      Do you have an OR flag on the preceding condition? The directives you have posted are perhaps over exemplified, please include your actual directives where possible. The directives you posted would trigger a 302 redirect, not a rewrite, as you seem to imply. (The susbstitution string is not strictly correct either - but maybe that's just your example?) You also don't need an additional condition if you are excluding a single URL path (but the conditions are arguably in the wrong order anyway).