Apache HTTP Server 版本 2.4
描述 | 服务器解析的 html 文档(服务器端包含) |
---|---|
状态 | 基础 |
模块标识符 | include_module |
源文件 | mod_include.c |
此模块提供一个过滤器,它将在文件发送到客户端之前处理文件。处理由特殊格式的 SGML 注释控制,称为 元素。这些元素允许条件文本、包含其他文件或程序,以及设置和打印环境变量。
服务器端包含由 INCLUDES
过滤器 实现。如果包含服务器端包含指令的文档被赋予扩展名 .shtml,则以下指令将使 Apache 解析它们并将生成的文档分配为 text/html
的 MIME 类型
AddType text/html .shtml AddOutputFilter INCLUDES .shtml
以下指令必须为包含 shtml 文件的目录提供(通常在 <Directory>
部分中,但此指令在 .htaccess
文件中也有效,如果 AllowOverride
Options
已设置)
Options +Includes
为了向后兼容,server-parsed
处理程序 也会激活 INCLUDES 过滤器。同样,Apache 会为任何 MIME 类型为 text/x-server-parsed-html
或 text/x-server-parsed-html3
的文档激活 INCLUDES 过滤器(生成的输出将具有 MIME 类型 text/html
)。
有关更多信息,请参阅我们的 服务器端包含教程。
默认情况下,处理服务器端包含的文件不再接受带有 PATH_INFO
(尾随路径信息)的请求。您可以使用 AcceptPathInfo
指令配置服务器以接受带有 PATH_INFO
的请求。
文档被解析为 HTML 文档,其中嵌入特殊命令作为 SGML 注释。命令的语法为
<!--#element attribute=value attribute=value ... -->
值通常用双引号括起来,但单引号 ('
) 和反引号 (`
) 也是可能的。许多命令只允许一个属性-值对。请注意,注释终止符 (-->
) 应以空格开头,以确保它不被视为 SSI 令牌的一部分。请注意,前导 <!--#
是一个令牌,不能包含任何空格。
允许的元素在以下表格中列出
元素 | 描述 |
---|---|
comment |
SSI 注释 |
config |
配置输出格式 |
echo |
打印变量 |
exec |
执行外部程序 |
fsize |
打印文件的大小 |
flastmod |
打印文件的最后修改时间 |
include |
包含文件 |
printenv |
打印所有可用变量 |
set |
设置变量的值 |
SSI 元素可能由除 mod_include
之外的模块定义。实际上,exec
元素由 mod_cgi
提供,并且只有在加载此模块时才可用。
此命令不输出任何内容。它唯一的用途是在文件中添加注释。这些注释不会被打印。
此语法在版本 2.4.21 及更高版本中可用。
<!--#comment Blah Blah Blah -->
或
<!--#comment text="Blah Blah Blah" -->
此命令控制解析的各个方面。有效属性为
echomsg
(Apache 2.1 及更高版本)该值是当 echo
元素尝试回显未定义的变量时发送回客户端的消息。这将覆盖任何 SSIUndefinedEcho
指令。
<!--#config echomsg="[Value Undefined]" -->
errmsg
该值是当解析文档时发生错误时发送回客户端的消息。这将覆盖任何 SSIErrorMsg
指令。
<!--#config errmsg="[Oops, something broke.]" -->
sizefmt
该值设置在显示文件大小时要使用的格式。有效值为 bytes
(以字节为单位的计数)或 abbrev
(以 Kb 或 Mb 为单位的计数,具体取决于情况),例如,大小为 1024 字节将被打印为“1K”。
<!--#config sizefmt="abbrev" -->
timefmt
该值是在打印日期时由 strftime(3)
库例程使用的字符串。
<!--#config timefmt=""%R, %B %d, %Y"" -->
此命令打印下面定义的 包含变量 之一。如果变量未设置,则结果由 SSIUndefinedEcho
指令确定。任何打印的日期都受当前配置的 timefmt
影响。
属性
var
decoding
指定 Apache 是否应该在进一步处理变量之前从变量中剥离编码。默认值为 none
,不会进行任何解码。如果设置为 url
,则将执行 URL 解码(也称为 %-编码;这适用于链接等 URL 中的使用)。如果设置为 urlencoded
,则将剥离与 application/x-www-form-urlencoded 兼容的编码(在查询字符串中找到)。如果设置为 base64
,则将解码 base64,如果设置为 entity
,则将剥离 HTML 实体编码。解码在对变量进行任何进一步编码之前完成。可以通过指定多个以逗号分隔的编码来剥离多个编码。解码设置将一直有效,直到遇到下一个解码属性或元素结束,以先发生者为准。
decoding
属性必须在相应的 var
属性之前才能生效。
encoding
指定 Apache 应该如何在输出之前对变量中包含的特殊字符进行编码。如果设置为 none
,则不会进行任何编码。如果设置为 url
,则将执行 URL 编码(也称为 %-编码;这适用于链接等 URL 中的使用)。如果设置为 urlencoded
,则将执行与 application/x-www-form-urlencoded 兼容的编码,应与查询字符串一起使用。如果设置为 base64
,则将执行 base64 编码。在 echo
元素的开头,默认设置为 entity
,导致实体编码(这在块级 HTML 元素的上下文中是合适的,例如一段文本)。这可以通过添加 encoding
属性来更改,该属性将一直有效,直到遇到下一个 encoding
属性或元素结束,以先发生者为准。
encoding
属性必须在相应的 var
属性之前才能生效。
<!--#echo encoding="entity" var="QUERY_STRING" -->
exec
命令执行给定的 shell 命令或 CGI 脚本。它要求服务器中存在 mod_cgi
。如果设置了 Options
IncludesNOEXEC
,则此命令将完全禁用。有效属性为
cgi
该值指定 CGI 脚本的(%-编码)URL 路径。如果路径没有以斜杠 (/) 开头,则它被认为相对于当前文档。通过此路径引用的文档被调用为 CGI 脚本,即使服务器通常不会将其识别为 CGI 脚本。但是,包含脚本的目录必须为 CGI 脚本启用(使用 ScriptAlias
或 Options
ExecCGI
)。
CGI 脚本被赋予来自客户端的原始请求的 PATH_INFO
和查询字符串 (QUERY_STRING
);这些不能在 URL 路径中指定。除了标准的 CGI 环境之外,包含变量也将对脚本可用。
<!--#exec cgi="/cgi-bin/example.cgi" -->
如果脚本返回 Location:
标头而不是输出,则这将被转换为 HTML 锚点。
include virtual
元素应优先于 exec cgi
使用。特别是,如果您需要将其他参数传递给 CGI 程序,使用查询字符串,这无法使用 exec cgi
完成,但可以使用 include virtual
完成,如下所示
<!--#include virtual="/cgi-bin/example.cgi?argument=value" -->
cmd
服务器将使用 /bin/sh
执行给定的字符串。除了通常的 CGI 变量集之外,包含变量 也对命令可用。
使用 #include virtual
几乎总是优于使用 #exec cgi
或 #exec cmd
。前者 (#include virtual
) 使用标准的 Apache 子请求机制来包含文件或脚本。它经过了更好的测试和维护。
此外,在某些平台上,例如 Win32,以及在使用 suexec 的 unix 上,您不能在 exec
指令中将参数传递给命令,也不能在命令中包含空格。因此,虽然以下内容在 unix 的非 suexec 配置下有效,但在 Win32 下或运行 suexec 时不会产生预期结果
<!--#exec cmd="perl /path/to/perlscript arg1 arg2" -->
此命令打印指定文件的大小,受 sizefmt
格式规范的影响。属性
file
此文件大小为 <!--#fsize file="mod_include.html" --> 字节。
file
的值不能以斜杠 (/
) 开头,也不能包含 ../
以引用当前目录上方的文件或文档根目录之外的文件。尝试这样做会导致错误消息:给定的路径高于根路径
。虚拟
此文件大小为 <!--#fsize virtual="/docs/mod/mod_include.html" --> 字节。
请注意,在许多情况下,这两个值完全相同。但是,file
属性不尊重 URL 空间别名。
此命令根据 timefmt
格式规范打印指定文件的最后修改日期。属性与 fsize
命令相同。
此命令将另一个文档或文件的内容插入解析的文件中。任何包含的文件都受通常的访问控制。如果包含解析文件的目录具有 Options IncludesNOEXEC
设置,则只包含具有文本 MIME 类型(text/plain
、text/html
等)的文档。否则,CGI 脚本将使用命令中给出的完整 URL(包括任何查询字符串)正常调用。
属性定义文档的位置,并且可以在一个 include 元素中出现多次;对于 include 命令给出的每个属性,都会依次执行包含操作。有效的属性是
file
../
,也不能是绝对路径。因此,您不能包含位于文档根目录之外或在目录结构中位于当前文档上方的文件。virtual
属性应始终优先于此属性使用。虚拟
该值是(百分号编码的)URL 路径。URL 不能包含方案或主机名,只能包含路径和可选的查询字符串。如果它不以斜杠 (/) 开头,则它被认为是相对于当前文档的。
从属性构建 URL,并且如果客户端访问该 URL,服务器将返回的输出包含在解析的输出中。因此,包含的文件可以嵌套。
如果指定的 URL 是 CGI 程序,则该程序将被执行,并且其输出将插入解析文件中指令的位置。您可以在 CGI url 中包含查询字符串
<!--#include virtual="/cgi-bin/example.cgi?argument=value" -->
include virtual
应优先于 exec cgi
用于将 CGI 程序的输出包含到 HTML 文档中。
如果 KeptBodySize
指令配置正确并且对包含的文件有效,则尝试将 POST 请求发送到封闭的 HTML 文档将被传递到子请求作为 POST 请求。如果没有该指令,所有子请求都将作为 GET 请求处理。
onerror
该值是(百分号编码的)URL 路径,如果先前尝试包含文件或虚拟属性失败,则会显示该路径。要有效,此属性必须在要覆盖的文件或虚拟属性之后指定。如果尝试包含 onerror 路径失败,或者没有指定 onerror,则将包含默认错误消息。
# 简单示例
<!--#include virtual="/not-exist.html" onerror="/error.html" -->
# 专用 onerror 路径
<!--#include virtual="/path-a.html" onerror="/error-a.html" virtual="/path-b.html" onerror="/error-b.html" -->
这将打印所有现有变量及其值的纯文本列表。特殊字符在输出之前进行实体编码(有关详细信息,请参阅 echo
元素)。没有属性。
<pre> <!--#printenv --> </pre>
这将设置变量的值。属性
var
value
decoding
指定 Apache 是否应该在进一步处理变量之前从变量中剥离编码。默认值为 none
,不进行解码。如果设置为 url
、urlencoded
、base64
或 entity
,则将分别执行 URL 解码、application/x-www-form-urlencoded 解码、base64 解码或 HTML 实体解码。可以通过逗号分隔来指定多个解码。解码设置将一直有效,直到遇到下一个解码属性或元素结束。decoding
属性必须位于相应的 var
属性之前才能生效。
encoding
指定 Apache 如何在设置变量之前对变量中包含的特殊字符进行编码。默认值为 none
,不进行编码。如果设置为 url
、urlencoding
、base64
或 entity
,则将分别执行 URL 编码、application/x-www-form-urlencoded 编码、base64 编码或 HTML 实体编码。可以通过逗号分隔来指定多个编码。编码设置将一直有效,直到遇到下一个编码属性或元素结束。encoding
属性必须位于相应的 var
属性之前才能生效。编码在剥离所有解码之后应用。
<!--#set var="category" value="help" -->
除了标准 CGI 环境中的变量之外,这些变量还可用于 echo
命令、if
和 elif
,以及文档调用的任何程序。
DATE_GMT
DATE_LOCAL
DOCUMENT_ARGS
include
SSI 指令调用的子请求,QUERY_STRING
将表示子请求的查询字符串,DOCUMENT_ARGS
将表示 SSI 文档的查询字符串。(在 Apache HTTP Server 2.4.19 及更高版本中可用。)DOCUMENT_NAME
DOCUMENT_PATH_INFO
PATH_INFO
的更多信息,请参阅指令 AcceptPathInfo
。DOCUMENT_URI
alias
或 directoryindex
),则会显示修改后的 URL。LAST_MODIFIED
QUERY_STRING_UNESCAPED
&
等特殊字符前面有反斜杠)。如果不存在查询字符串,则不会设置它。如果不需要 shell 转义,请使用 DOCUMENT_ARGS
。USER_NAME
在大多数情况下,变量替换会在引号字符串中完成,这些字符串可能合理地作为 SSI 指令的参数出现。这包括 config
、exec
、flastmod
、fsize
、include
、echo
和 set
指令。如果 SSILegacyExprParser
设置为 on
,则替换也会发生在条件运算符的参数中。您可以使用反斜杠引用将文字美元符号插入字符串中
<!--#set var="cur" value="\$test" -->
如果需要在字符序列的中间替换变量引用,而该字符序列本身可能被视为有效的标识符,则可以通过将引用括在花括号中来消除歧义,类似于 shell 替换
<!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" -->
如果 REMOTE_HOST
为 "X
" 且 REQUEST_METHOD
为 "Y
",则这将导致 Zed
变量设置为 "X_Y
"。
基本流程控制元素是
<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->
if
元素的工作原理类似于编程语言中的 if 语句。测试条件将被评估,如果结果为真,则直到下一个 elif
、else
或 endif
元素之间的文本将包含在输出流中。
elif
或 else
语句用于在原始 test_condition 为假时将文本放入输出流中。这些元素是可选的。
endif
元素结束 if
元素,并且是必需的。
test_condition 是一个布尔表达式,它遵循 ap_expr 语法。可以使用 SSILegacyExprParser
将语法更改为与 Apache HTTPD 2.2.x 兼容。
使用 var
元素设置的 SSI 变量将导出到请求环境中,并且可以使用 reqenv
函数访问。作为快捷方式,函数名 v
也可在 mod_include
内部使用。
以下示例将打印 "from local net",如果客户端 IP 地址属于 10.0.0.0/8 子网。
<!--#if expr='-R "10.0.0.0/8"' -->
from local net
<!--#else -->
from somewhere else
<!--#endif -->
以下示例将打印 "foo is bar",如果变量 foo
设置为值 "bar"。
<!--#if expr='v("foo") = "bar"' -->
foo is bar
<!--#endif -->
另请参阅:Apache HTTP Server 中的表达式,以获取完整的参考和示例。受限函数在 mod_include
内部不可用
本节描述了如果 SSILegacyExprParser
设置为 on
,则 #if expr
元素的语法。
string
-A string
如果字符串表示的 URL 可通过配置访问,则为真,否则为假。这在页面上的内容需要对未经授权查看 URL 的用户隐藏时很有用,例如指向该 URL 的链接。请注意,URL 仅测试是否会授予访问权限,而不是测试 URL 是否存在。
<!--#if expr="-A /private" -->
点击 <a href="/private">这里</a> 访问私有信息。
<!--#endif -->
string1 = string2
string1 == string2
string1 != string2
将 string1 与 string2 进行比较。如果 string2 的形式为 /string2/
,则将其视为正则表达式。正则表达式由 PCRE 引擎实现,其语法与 perl 5 中的语法相同。请注意,==
只是 =
的别名,其行为完全相同。
如果匹配正值(=
或 ==
),则可以捕获正则表达式的分组部分。捕获的部分存储在特殊变量 $1
.. $9
中。正则表达式匹配的整个字符串存储在特殊变量 $0
中
<!--#if expr="$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/" -->
<!--#set var="session" value="$1" -->
<!--#endif -->
string1 < string2
string1 <= string2
string1 > string2
string1 >= string2
strcmp(3)
)。因此,字符串 "100" 小于 "20"。( test_condition )
! test_condition
test_condition1 && test_condition2
test_condition1 || test_condition2
"=
" 和 "!=
" 的绑定优先级高于 "&&
" 和 "||
"。"!
" 的绑定优先级最高。因此,以下等效
<!--#if expr="$a = test1 && $b = test2" -->
<!--#if expr="($a = test1) && ($b = test2)" -->
布尔运算符 &&
和 ||
具有相同的优先级。因此,如果要将此类运算符绑定得更紧密,则应使用括号。
任何无法识别为变量或运算符的内容都将被视为字符串。字符串也可以用引号括起来:'string'
。未加引号的字符串不能包含空格(空格和制表符),因为空格用于分隔变量等标记。如果在一行中找到多个字符串,则使用空格将它们连接起来。所以,
string1 string2
导致 string1 string2
和
'string1 string2'
导致 string1 string2
。
如果表达式变得更加复杂,并且处理速度明显变慢,则可以尝试根据评估规则对其进行优化
&&
和 ||
)尽可能地进行短路计算。结合上面关于从左到右评估的规则,这意味着,mod_include
首先评估左侧表达式。如果左侧结果足以确定最终结果,则处理在此停止。否则,它会评估右侧并从左右结果计算最终结果。$1
.. $9
)。如果要查看特定表达式的处理方式,可以重新编译 mod_include
,使用 -DDEBUG_INCLUDE
编译器选项。这会为每个解析的表达式插入标记器信息、解析树以及如何将其评估到发送给客户端的输出中。
所有不打算用作正则表达式分隔符的斜杠都必须转义。这与它们对正则表达式引擎的含义无关。
描述 | 结束包含元素的字符串 |
---|---|
语法 | SSIEndTag tag |
默认值 | SSIEndTag "-->" |
上下文 | 服务器配置、虚拟主机 |
状态 | 基础 |
模块 | mod_include |
此指令更改 mod_include
用于标记包含元素结束的字符串。
SSIEndTag "%>"
描述 | 出现 SSI 错误时显示的错误消息 |
---|---|
语法 | SSIErrorMsg message |
默认值 | SSIErrorMsg "[an error occurred while processing this directive]" |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | 全部 |
状态 | 基础 |
模块 | mod_include |
当 mod_include
遇到错误时,SSIErrorMsg
指令会更改显示的错误消息。对于生产服务器,您可能需要考虑将默认错误消息更改为 "<!-- Error -->"
,这样就不会向用户显示该消息。
此指令与 <!--#config errmsg=message -->
元素的效果相同。
SSIErrorMsg "<!-- Error -->"
描述 | 控制服务器是否生成 ETag。 |
---|---|
语法 | SSIETag on|off |
默认值 | SSIETag off |
上下文 | 目录、.htaccess |
状态 | 基础 |
模块 | mod_include |
兼容性 | 在 2.2.15 及更高版本中可用。 |
在正常情况下,由 mod_include
过滤的文件可能包含动态生成的元素,或者可能独立于原始文件更改的元素。因此,默认情况下,服务器被要求通过将 no-etag
添加到请求注释中,不要为响应生成 ETag
标头。
SSIETag
指令会抑制此行为,并允许服务器生成 ETag
标头。这可用于启用输出缓存。请注意,后端服务器或动态内容生成器可能会生成自己的 ETag,忽略 no-etag
,并且此 ETag 将由 mod_include
无论此设置的值如何,都会传递。SSIETag
可以采用以下值
off
no-etag
将被添加到请求注释中,并且服务器被要求不要生成 ETag。如果服务器忽略 no-etag
的值并仍然生成 ETag,则会尊重 ETag。on
描述 | 控制服务器是否生成 Last-Modified 标头。 |
---|---|
语法 | SSILastModified on|off |
默认值 | SSILastModified off |
上下文 | 目录、.htaccess |
状态 | 基础 |
模块 | mod_include |
兼容性 | 在 2.2.15 及更高版本中可用。 |
在正常情况下,由 mod_include
过滤的文件可能包含动态生成的元素,或者可能独立于原始文件更改的元素。因此,默认情况下,Last-Modified
标头将从响应中删除。
SSILastModified
指令会覆盖此行为,并允许在响应中存在时尊重 Last-Modified
标头,或者在响应为文件且标头不存在时将其添加到响应中。这可用于启用输出缓存。SSILastModified
可以采用以下值
off
Last-Modified
标头将从响应中删除,除非 XBitHack
指令设置为 full
,如下所述。on
Last-Modified
标头已存在于响应中,则会尊重它,如果响应为文件且标头不存在,则会将其添加到响应中。SSILastModified
指令优先于 XBitHack
指令。描述 | 启用条件表达式的兼容模式。 |
---|---|
语法 | SSILegacyExprParser on|off |
默认值 | SSILegacyExprParser off |
上下文 | 目录、.htaccess |
状态 | 基础 |
模块 | mod_include |
兼容性 | 在 2.3.13 及更高版本中可用。 |
从 2.3.13 版本开始,mod_include
已切换到新的 ap_expr 语法,用于 #if
流程控制元素中的条件表达式。此指令允许切换到 旧语法,该语法与 Apache HTTPD 2.2.x 及更早版本兼容。
描述 | 开始包含元素的字符串 |
---|---|
语法 | SSIStartTag tag |
默认值 | SSIStartTag "<!--#" |
上下文 | 服务器配置、虚拟主机 |
状态 | 基础 |
模块 | mod_include |
此指令更改 mod_include
用于标记要处理的包含元素的字符串。
如果您有两个服务器解析文件的输出,每个服务器处理不同的命令(可能在不同的时间),则可能需要使用此选项。
SSIStartTag "<%" SSIEndTag "%>"
上面给出的示例还指定了匹配的 SSIEndTag
,这将允许您使用 SSI 指令,如下面的示例所示
<%printenv %>
描述 | 配置日期字符串显示的格式 |
---|---|
语法 | SSITimeFormat formatstring |
默认值 | SSITimeFormat "%A, %d-%b-%Y %H:%M:%S %Z" |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | 全部 |
状态 | 基础 |
模块 | mod_include |
此指令更改回显 DATE
环境变量时日期字符串显示的格式。formatstring
与 C 标准库中的 strftime(3)
相同。
此指令与 <!--#config timefmt=formatstring -->
元素的效果相同。
SSITimeFormat "%R, %B %d, %Y"
上面的指令会导致时间以 "22:26, June 14, 2002" 的格式显示。
描述 | 回显未设置的变量时显示的字符串 |
---|---|
语法 | SSIUndefinedEcho string |
默认值 | SSIUndefinedEcho "(none)" |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | 全部 |
状态 | 基础 |
模块 | mod_include |
此指令更改 mod_include
在变量未设置并被 "回显" 时显示的字符串。
SSIUndefinedEcho "<!-- undef -->"
描述 | 解析具有执行位的文件的 SSI 指令 |
---|---|
语法 | XBitHack on|off|full |
默认值 | XBitHack off |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | 选项 |
状态 | 基础 |
模块 | mod_include |
XBitHack
指令控制对普通 html 文档的解析。此指令仅影响与 MIME 类型 text/html
关联的文件。XBitHack
可以采用以下值
off
on
text/html
文件都将被视为服务器解析的 html 文档。full
on
相同,但还会测试组执行位。如果设置了组执行位,则将返回文件的 Last-modified
日期设置为文件的最后修改时间。如果未设置,则不会发送最后修改日期。设置此位允许客户端和代理缓存请求的结果。除非您确保每个 SSI 脚本的组执行位都未设置,否则您不会想要使用 full 选项,这些脚本可能会 #include
CGI 或在每次命中时产生不同的输出(或可能在后续请求中更改)。
当
设置为 SSILastModified
on
时,
指令优先于 SSILastModified
指令。XBitHack