.htaccess如果文件不存在则执行其他操作

时间:2012-09-16 22:07:42

标签: .htaccess

我们将.htaccess与anchor标签结合使用来提供文件并隐藏服务器目录结构。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /_docu/clients/$1/$2/$3.pdf [NC,L]

例如,所有文件都存储在/public_html/_docu/clients/下,并在该文件夹中列出所有客户端,然后在每个客户端下列出他们的项目。但是,文件的锚标记只能是:

http://mydomain.com/client-name/proj-name/docname.pdf

(/ _docu / clients /被省略 - 这是有充分理由的)。上面的.htaccess会抓取client-nameproj-namedocname并从正确的文件夹中提供它:

http://mydomain.com/_docu/clients/client-name/proj-name/docname.pdf

虽然在地址栏中保留了错误的(隐藏的)目录结构。

我希望处理不存在的文档的错误情况。这应该永远不会发生,但它可以。任何人都可以提出一种解决方法吗?功能上类似于“if fileexist($ 1 / $ 2 /%3.pdf)”的东西可以在.htaccess文件中以某种方式构建吗?


编辑:

延迟回应,因为JL的答案需要进行研究和实验。谢谢,乔恩,为了向正确的方向轻轻推动,但我还没有让它工作。这是我试过的:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# check if the requested file exists in the "_docu/clients" directory
RewriteCond %{DOCUMENT_ROOT}/_docu/clients/$1/$2/$3.pdf -f
RewriteRule ^([a-z0-9])/([a-z0-9])/([a-z0-9]*).pdf$ /_docu/clients/$1/$2/$3.pdf [NC,L]
RewriteRule ^(.*)$ /errors/404.php [L]

认为应该做的是:

  1. 如果http://mydomain.com/_docu/clients/$1/$2/$3.pdf不存在,
  2. 转到页面http://mydomain.com/errors/404.php
  3. 实际结果是“内部服务器错误”消息。


    编辑二:

    最新变化:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} ^/([a-z0-9])/([a-z0-9])/([a-z0-9]*).pdf$
    RewriteCond %{DOCUMENT_ROOT}/_data/cli/%1/%2/%3.pdf -f
    RewriteRule ^([a-z0-9])/([a-z0-9])/([a-z0-9]*).pdf$ /_data/cli/$1/$2/$3.pdf [NC,L]
    RewriteCond %{ENV:REDIRECT_STATUS} !200
    RewriteRule ^(.*)$ /metshare/404.php [L]
    

    这个问题是合法页面也被定向到404.php

    给未来读者的信息:

    所有上述问题都在Jon Lin的最终答案中得到了解决。在检测到问题后,他修改了答案,直到它成为一个完美的,有效的解决方案。我正在抛弃上述内容,因为对于想要比较版本的人来说,有一些优秀的ULO(计划外学习机会)。

1 个答案:

答案 0 :(得分:1)

你需要使用这样的条件:

RewriteCond %{DOCUMENT_ROOT}/_docu/clients%{REQUEST_URI} -f

这样你的规则就像是:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# check if the requested file exists in the "_docu/clients" directory
RewriteCond %{DOCUMENT_ROOT}/_docu/clients%{REQUEST_URI} -f
RewriteRule ^ /_docu/clients%{REQUEST_URI} [L]

编辑:回复编辑问题

你不能这样做:

RewriteCond %{DOCUMENT_ROOT}/_docu/clients/$1/$2/$3.pdf -f

由于$ 1 / $ 2 / $ 3的反向引用尚不存在,因此它们在RewriteRule的分组中匹配,此时尚未发生。但你可以尝试这样的事情:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# check if the requested file exists in the "_docu/clients" directory
RewriteCond %{REQUEST_URI} ^/([a-z0-9])/([a-z0-9])/([a-z0-9]*).pdf$
RewriteCond %{DOCUMENT_ROOT}/_docu/clients/%1/%2/%3.pdf -f
RewriteRule ^([a-z0-9])/([a-z0-9])/([a-z0-9]*).pdf$ /_docu/clients/$1/$2/$3.pdf [NC,L]

RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /errors/404.php [L]

基本上在之前的%{REQUEST_URI}中针对RewriteCond创建匹配,然后使用以下%N中的RewriteCond反向引用。