如何在SSI的#include指令中使用DOCUMENT_URI变量引入目标文件
解决方案
问题根因
你遇到的错误由两个核心原因导致:
- SSI的
#include指令默认不会解析双引号内的变量名,你直接写virtual="DOCUMENT_URI"时,系统会把DOCUMENT_URI作为字面量路径查找文件,自然无法匹配到真实路径。 - 原有重写规则会拦截所有请求,包括你要引入的目标页面请求,导致
#include请求又被重定向到shell.shtml形成死循环,最终触发执行错误。
修复步骤
1. 修改.htaccess重写规则,避免循环
给重写规则加上判断条件,排除真实存在的文件和目录,确保你要引入的静态页面、组件资源不会被重写:
RewriteEngine On # 排除真实存在的文件 RewriteCond %{REQUEST_FILENAME} !-f # 排除真实存在的目录 RewriteCond %{REQUEST_FILENAME} !-d # 原有重写逻辑保持不变 RewriteRule ^(.*)$ /framework/parts/shell.shtml?url=$1 [QSA,L]
修改后先测试写死路径的#include语句:<!--#include virtual="/private/index.html" -->,确认可以正常加载内容,说明循环问题已解决。
2. 修正SSI变量引用语法
SSI中要在指令参数里引用变量,需要用${变量名}的格式包裹变量,把你原有#include行替换为以下写法即可:
<!--#include virtual="${DOCUMENT_URI}" -->
如果测试时发现DOCUMENT_URI取到的值是shell.shtml而非原请求路径,可以改用重写时传入的url参数构造路径:
<!--#include virtual="/${QUERY_STRING#url=}" -->
这个写法会自动提取查询参数中url对应的路径值,完成文件引入。
可选补充配置
如果以上操作后仍然报错,可以检查Apache站点配置中对应目录的Options指令,确保已开启Includes(你之前显式指定路径可正常运行,一般无需额外修改)。
内容的提问来源于stack exchange,提问作者cwhiii
相关产品推荐
相关产品推荐

