<-
Apache > HTTP 服务器 > 文档 > 版本 2.4

将 URL 映射到文件系统位置

可用语言:  en  |  fr  |  ja  |  ko  |  tr 

本文档解释了 Apache HTTP Server 如何使用请求的 URL 来确定要从中提供文件的系统位置。

Support Apache!

另请参阅

top

相关模块和指令

top

DocumentRoot

在决定为给定请求提供哪个文件时,httpd 的默认行为是获取请求的 URL-Path(URL 中主机名和端口后面的部分),并将其添加到配置 文件中指定的 DocumentRoot 的末尾。因此,DocumentRoot 下面的文件和目录构成了从 Web 可见的 基本文档树。

例如,如果 DocumentRoot 设置为 /var/www/html,那么对 http://www.example.com/fish/guppies.html 的请求将导致文件 /var/www/html/fish/guppies.html 被提供给请求的客户端。

如果请求的是目录(即以 / 结尾的路径),则从该目录提供的文件由 DirectoryIndex 指令定义。例如,如果 DocumentRoot 设置如上,并且您要设置

DirectoryIndex index.html index.php

那么对 http://www.example.com/fish/ 的请求将导致 httpd 尝试提供文件 /var/www/html/fish/index.html。如果该文件不存在,它将接下来尝试提供文件 /var/www/html/fish/index.php

如果这两个文件都不存在,下一步是尝试提供目录索引,如果 mod_autoindex 已加载并配置为允许这样做。

httpd 还能够进行 虚拟主机,其中服务器接收对多个主机的请求。在这种情况下,可以为每个虚拟主机指定不同的 DocumentRoot,或者,可以使用模块 mod_vhost_alias 提供的指令根据请求的 IP 地址或主机名动态确定提供内容的适当位置。

DocumentRoot 指令在您的主服务器配置文件 (httpd.conf) 中设置,并且可能在您创建的每个附加 虚拟主机 中设置一次。

top

DocumentRoot 之外的文件

通常情况下,需要允许对不在 DocumentRoot 下面的文件系统的部分进行 Web 访问。httpd 提供了几种不同的方法来实现这一点。在 Unix 系统上,符号链接可以将文件系统的其他部分引入 DocumentRoot 下面。出于安全原因,httpd 仅在相关目录的 Options 设置包含 FollowSymLinksSymLinksIfOwnerMatch 时才会遵循符号链接。

或者,Alias 指令将文件系统的任何部分映射到 Web 空间。例如,使用

Alias "/docs" "/var/web"

URL http://www.example.com/docs/dir/file.html 将从 /var/web/dir/file.html 提供。ScriptAlias 指令的工作方式相同,但附加的效果是,位于目标路径下的所有内容都被视为 CGI 脚本。

对于需要更多灵活性的情况,您可以使用 AliasMatchScriptAliasMatch 指令来进行强大的 正则表达式 匹配和替换。例如,

ScriptAliasMatch "^/~([a-zA-Z0-9]+)/cgi-bin/(.+)"   "/home/$1/cgi-bin/$2"

将对 http://example.com/~user/cgi-bin/script.cgi 的请求映射到路径 /home/user/cgi-bin/script.cgi,并将结果文件视为 CGI 脚本。

top

用户目录

传统上,在 Unix 系统上,特定用户的主目录可以称为 ~user/。模块 mod_userdir 将此想法扩展到 Web,允许访问每个用户主目录下的文件,使用以下 URL。

http://www.example.com/~user/file.html

出于安全原因,从 Web 直接访问用户主目录是不合适的。因此,UserDir 指令指定用户主目录下的一个目录,其中存放 Web 文件。使用 Userdir public_html 的默认设置,上面的 URL 映射到类似 /home/user/public_html/file.html 的目录下的文件,其中 /home/user/ 是用户在 /etc/passwd 中指定的主目录。

还有几种其他形式的 Userdir 指令,您可以在 /etc/passwd 不包含主目录位置的系统上使用。

有些人发现“~”符号(通常在 Web 上编码为 %7e)很笨拙,更喜欢使用替代字符串来表示用户目录。mod_userdir 不支持此功能。但是,如果用户的 home 目录以规律的方式构建,那么可以使用 AliasMatch 指令来实现所需的效果。例如,要使 http://www.example.com/upages/user/file.html 映射到 /home/user/public_html/file.html,请使用以下 AliasMatch 指令

AliasMatch "^/upages/([a-zA-Z0-9]+)(/(.*))?$"   "/home/$1/public_html/$3"
top

URL 重定向

上面各节中讨论的配置指令告诉 httpd 从文件系统的特定位置获取内容并将其返回给客户端。有时,希望改为通知客户端请求的内容位于不同的 URL,并指示客户端使用新 URL 发出新的请求。这称为重定向,由 Redirect 指令实现。例如,如果 DocumentRoot 下的目录 /foo/ 的内容移动到新目录 /bar/,您可以指示客户端按以下方式请求新位置的内容

Redirect permanent "/foo/"   "http://www.example.com/bar/"

这将重定向以 /foo/ 开头的任何 URL-Path 到 www.example.com 服务器上的相同 URL 路径,将 /bar/ 替换为 /foo/。您可以将客户端重定向到任何服务器,而不仅仅是源服务器。

httpd 还提供了一个 RedirectMatch 指令,用于解决更复杂的重写问题。例如,要将对站点主页的请求重定向到另一个站点,但保留所有其他请求,请使用以下配置

RedirectMatch permanent "^/$"    "http://www.example.com/startpage.html"

或者,要将一个站点上的所有页面临时重定向到另一个站点上的特定页面,请使用以下方法

RedirectMatch temp ".*"  "http://othersite.example.com/startpage.html"
top

反向代理

httpd 还允许您将远程文档引入本地服务器的 URL 空间。这种技术称为反向代理,因为 Web 服务器充当代理服务器,从远程服务器获取文档并将其返回给客户端。它与正常的(正向)代理不同,因为对于客户端来说,它看起来像是文档起源于反向代理服务器。

在以下示例中,当客户端请求 /foo/ 目录下的文档时,服务器从 internal.example.com 上的 /bar/ 目录获取这些文档,并将它们返回给客户端,就好像它们来自本地服务器一样。

ProxyPass "/foo/" "http://internal.example.com/bar/"
ProxyPassReverse "/foo/" "http://internal.example.com/bar/"
ProxyPassReverseCookieDomain internal.example.com public.example.com
ProxyPassReverseCookiePath "/foo/" "/bar/"

ProxyPass 配置服务器以获取适当的文档,而 ProxyPassReverse 指令重写来自 internal.example.com 的重定向,以便它们针对本地服务器上的适当目录。类似地,ProxyPassReverseCookieDomainProxyPassReverseCookiePath 重写由后端服务器设置的 cookie。

但是,需要注意的是,文档内部的链接不会被重写。因此,internal.example.com 上的任何绝对链接都将导致客户端跳出代理服务器,并直接从 internal.example.com 请求。您可以使用 mod_substitute 在将页面提供给客户端时修改这些链接(和其他内容)。

Substitute "s/internal\.example\.com/www.example.com/i"

对于更复杂的 HTML 和 XHTML 中链接的重写,还可以使用 mod_proxy_html 模块。它允许您创建需要重写的 URL 映射,以便可以处理复杂的代理场景。

top

重写引擎

当需要更强大的替换时,mod_rewrite 提供的重写引擎很有用。此模块提供的指令可以使用请求的特征(如浏览器类型或源 IP 地址)来决定从哪里提供内容。此外,mod_rewrite 可以使用外部数据库文件或程序来确定如何处理请求。重写引擎能够执行上面讨论的所有三种类型的映射:内部重定向(别名)、外部重定向和代理。在 详细的 mod_rewrite 文档 中讨论了许多使用 mod_rewrite 的实际示例。

top

文件未找到

不可避免地,会请求到文件系统中找不到匹配文件的 URL。这可能由于多种原因导致。在某些情况下,可能是由于将文档从一个位置移动到另一个位置。在这种情况下,最好使用 URL 重定向 来通知客户端资源的新位置。这样,即使资源位于新位置,您也可以确保旧书签和链接继续有效。

导致“文件未找到”错误的另一个常见原因是意外地错误输入 URL,无论是直接在浏览器中还是在 HTML 链接中。httpd 提供了模块 mod_speling(原文如此)来帮助解决此问题。当此模块被激活时,它将拦截“文件未找到”错误并查找具有类似文件名的资源。如果找到一个这样的文件,mod_speling 将向客户端发送 HTTP 重定向,通知它正确的位置。如果找到多个“接近”的文件,则会向客户端呈现可用备选方案的列表。

mod_speling 的一个特别有用的功能是,它将比较文件名而不考虑大小写。这可以帮助用户不知道 URL 和 Unix 文件系统区分大小写的系统。但是,将 mod_speling 用于除偶尔的 URL 校正之外的任何用途都会给服务器带来额外的负载,因为每个“不正确”的请求都会随之进行 URL 重定向,以及来自客户端的新请求。

mod_dir 提供了 FallbackResource,它可以用来将虚拟 URI 映射到一个真实的资源,然后由它来提供服务。在实现“前端控制器”时,这是一个非常有用的 mod_rewrite 的替代方案。

如果所有定位内容的尝试都失败,httpd 将返回一个带有 HTTP 状态码 404(文件未找到)的错误页面。此页面的外观由 ErrorDocument 指令控制,并且可以像 自定义错误响应 文档中所述那样以灵活的方式进行自定义。

top

其他 URL 映射模块

其他可用于 URL 映射的模块包括

可用语言:  en  |  fr  |  ja  |  ko  |  tr 

top

评论

注意
这不是一个问答区。此处放置的评论应针对改进文档或服务器的建议,如果这些评论已被实施或被认为无效/偏离主题,则可能会被我们的版主删除。有关如何管理 Apache HTTP Server 的问题,应发送到我们的 IRC 频道 #httpd(在 Libera.chat 上),或发送到我们的 邮件列表