【问题标题】:mod_rewrite: If the file exists in another directory, serve that one insteadmod_rewrite:如果文件存在于另一个目录中,则改为提供该文件
【发布时间】:2012-08-20 09:58:56
【问题描述】:

我有一个网站example.com/test/。假设网站的布局是这样的:

example.com
└── test/
    ├── assets/
    │   └─ stylesheet.css
    │
    ├── .htaccess
    └── index.php

index.php 这里是路由器,现在这样做显然很酷。

每当用户请求像example.com/test/stylesheet.css 这样的页面时,我想检查assets/ 是否有该文件,如果有,则提供该文件,而不是将URL 提供给index.php。理想情况下,以下方法会起作用:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond assets/%{REQUEST_FILENAME} -f
RewriteRule ^(.+)$ assets/$1

但由于%{REQUEST_FILENAME} 是绝对路径,assets/%{REQUEST_FILENAME} 原来是类似于assets/home/public/test/stylesheet.css%{REQUEST_URI} 也好不到哪里去:它变成了assets/test/stylesheet.css。我也看了this question,但答案也没有用。

有什么方法可以在不借助 PHP 的情况下做到这一点? (如果没有,我就用 PHP 的readfile,但我不想担心 LFI 什么的。)

【问题讨论】:

    标签: .htaccess mod-rewrite


    【解决方案1】:

    尝试使用 the %{DOCUMENT_ROOT}%{REQUEST_URI} 变量

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{DOCUMENT_ROOT}/assets/%{REQUEST_URI} -f
    RewriteRule ^(.+)$ assets/$1
    

    编辑:我明白了,试试这个:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_URI} ^/([^/]+)/(.+)$
    RewriteCond %{DOCUMENT_ROOT}/%1/assets/%2 -f
    RewriteRule ^(.*)$ /%1/assets/%2 [L,R]
    

    【讨论】:

    • 我试过了:问题是%{REQUEST_URI}test/stylesheet.css。实际重写变成%{DOCUMENT_ROOT}/assets/test/stylesheet.css,这里我需要%{DOCUMENT_ROOT}/test/assets/stylesheet.css
    • @arxanas 等等,所以任何路径中都有一个assets 文件夹?如果有人请求/a/b/c/d/e/f/foo.css,那会转到/a/assets/b/c/d/e/f/foo.css 还是/a/b/c/d/e/f/assets/foo.css
    • .htaccess 位于test/ 目录中,因此它不必匹配 any 第一个目录。但预期的行为是/a/assets/b/c/d/e/f/foo.css
    • @arxanas 啊我明白了,看到编辑,你可以使用% 反向引用来匹配URI
    • 完美运行,谢谢!但这是否容易受到路径遍历攻击?我不应该这么想,但我不想在生产中被证明是错误的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 2012-03-01
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多