简体   繁体   中英

apache mod_rewrite: How to add different rewrite rules for same directory depending on file existence in other directory?

I'm currently having a bit of trouble to configure the rewrite rule(s) in a .htaccess file for an Apache 2.2 server with mod_rewrite . Here's the general idea of what I want to do:

Let's say the server domain is example.com/, and all requests to example.com/abc/ and paths below that directory shall be rewritten. There are two scenarios:

  1. Requests directly to example.com/abc/ or example.com/abc/index.php shall become requests to example.com/index.php with an additional parameter to indicate the original directory of the request. To give a few examples:

    • example.com/abc/ ==> example.com/abc/index.php?directory=abc
    • example.com/abc/?foo=1&bar=2 ==> example.com/abc/index.php?directory=abc&foo=1&bar=2
    • example.com/abc/?a=b&c=d ==> example.com/abc/index.php?directory=abc&a=b&c=d
    • ... and so on
  2. Requests to files within example.com/abc/ shall become requests to files in example.com/, if these files exist there. parameter to indicate the current directory. To give a few examples:

    • example.com/abc/image.png ==> example.com/image.png (if the later file exists)
    • example.com/abc/sub/file.css ==> example.com/sub/file.css (if the later file exists)
    • example.com/abc/foo/bar/baz/name.js ==> example.com/foo/bar/baz/name.js (if the later file exists)
    • ... and so on.

The content of my .htaccess currently looks similar to this:

RewriteEngine on
Options FollowSymLinks
RewriteBase /

# rule for files in abc/: map to files in root directory
RewriteCond $1 -f
RewriteRule ^abc/(.*?)$ $1

# rule for abc/index.php: map to index.php?directory=abc&...
RewriteCond $1 !-f
RewriteRule ^abc/(.*?)$ index.php?directory=abc&$1 [QSA]

The later rule seems to work, requests to example.com/abc/index.php get rewritten as intended. However, that does not work for files in the abc/ directory. Any hints on what I am doing wrong here and how to solve that problem are appreciated. What changes have to be applied to .htaccess to get things working as described?

I've found a working solution:

RewriteEngine on
Options FollowSymLinks
RewriteBase /

# rule for file in abc/: map them to files in document root
RewriteCond %{DOCUMENT_ROOT}/$1 -f
RewriteRule ^abc/(.*?)$ %{DOCUMENT_ROOT}/$1 [L]

# rule for abc/index.php: map to index.php?directory=abc&...
RewriteRule ^abc/(.*?)$ %{DOCUMENT_ROOT}/index.php?directory=abc&$1 [QSA,L]

The two main differences are:

  • using the [L] flag to indicate that no further rules should be considered after a rule matches - that was probably the problem why only the last rule seemed to work.
  • prefacing locations in the condition and the rewrite location with %{DOCUMENT_ROOT} to get absolute paths.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM