div.example { background-color: rgba(229, 236, 243, 1); color: rgba(0, 0, 0, 1); padding: 0.5em; margin: 1em 2em 1em 1em }
div.warning { border: 1px solid rgba(255, 0, 0, 1) }

下面的文章翻译自Apache HTTP Server的官方文档 : Mapping URLs to Filesystem Locations

本文解释了Apache HTTP Server如何应用请求的URL来决定获取文档的文件系统位置。

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作为客户端响应。

如果请求的是一个目录(也就是 path以/结尾), 那么响应的文件是由 DirectoryIndex 指令指定的。例如如果DocumentRoot按照上面的设置,然后设置

 DirectoryIndex index.html index.php

如果这些文件不存在,那么如果mod_autoindex模块被加载并且配置允许的话,就会尝试提供一个目录索引。

httpd还具有Virtual Hosting的能力,Virtual Hosting可以让httpd能够接受多个主机的请求。在这种情况下,可以为每一个虚拟主机指定一个DocumentRoot,mod_vhost_alias 模块提供的目录可以被用来根据请求的IP地址或者主机名动态决定提供文件的合适位置。

DocumentRoot指令可以被设置在主配置文件中(httpd.conf),但是更有可能的是,为每一个虚拟主机指定一个 DocumentRoot。

DocumentRoot之外的文件

经常会有这样的情况:我们需要web来访问DocumentRoot之外的文件。httpd提供了几种方式来实现这个需求。在Unix系统中,软连接(symbolic links)可以用来将其他位置的文件放到DocumentRoot之内。 为了安全考虑,httpd只有在相关目录的Options设置中包含有FollowSymLinks 或者SymLinksIfOwnerMatch时才会允许访问软连接。

或者我们可以使用Alias指令来将文件系统中的任意位置映射到web空间中。 例如,设置

Alias "/docs" "/var/web"

那么请求http://www.example.com/docs/dir/file.html将会被响应 /var/web/dir/file.html。 ScriptAlias 指令能够起到同样的效果,只不过请求访问的到目标文件会被作为CGI脚本看待。

对于需要更大灵活性的情况,我们可以使用AliasMatch 和ScriptAliasMatch 指令来指定基于匹配和替换的强大的正则表达式。例如:

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脚本看待。

用户目录(user-dir)

在传统的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中指定的用户家目录。

对于/etc/passwd中不存在用户家目录路径的系统,我们可以使用其他几种形式的UserDir。

有些人认为在URL中使用~符号(经常会被url转码为%7e)是不合适,他们更喜欢使用另外一个字符串来代表用户家目录。mod_userdir模块并不支持这个功能。但是,如果用户的家目录是按照一个有规律的方式组织的话,那么使用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"

URL重定向

上面讨论的配置指令用来让httpd从文件系统中的特定位置获得文件来响应客户端。 但是有时,我们期待能够告诉客户端请求的内容位于另一个URL中,从而使得客户端可以发送一个新的对于这个URL的请求。这种机制被称为 重定向(redirection), 可以使用Redirect 指令来实现。例如,如果DocumentRoot下的/foo/目录中的内容全部移到了另一个目录/bar/下面,你可以指示客户端重新发送一个请求来获取新目录下面的文件。

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

上面的配置将会将以/foo/开头的URL-Path重定向到www.example.com下面的将/foo/替换为/bar/的相同路径上,例如 http://www.yousite.com/foo/fish/guppies.html 将会被重定向到 http://www.example.com/bar/fish/guppies.html。 就像上面的例子那样,我们可以将客户端重定向到任意的server,并不局限于原始的server。

httpd同样提供了RedirectMatch指令来应对更加复杂的重定向问题。例如,为了将站点的首页重定向到另一个站点,但是其他的访问并不重定向,可以使用下面的配置:

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

或者,可以像下面这样将一个站点的所有页面全部重定向到另一个站点中:

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

注释1: 上面两个配置中的 permanent 和 temp将会作用到客户端收到的重定向响应(301)的头信息中。

注释2: 下面将会讲到httpd的反向代理,在此我们首先需要明确重定向最重要的特性是: 服务端会主动让客户端接受到301 重定向响应,然后让客户端重新发起一个新的请求,也就是说客户端对于这个过程是了解的。而反向代理则正好相反,服务端会尽量将真实的资源来源(被代理服务器)隐藏起来,而让客户端感觉就像这些资源真的就来自于代理服务器一样。

反向代理(Reverse Proxy)

httpd同样允许我们将远程站点的文档放到本地站点的URL空间中。这种技术叫做反向代理(reverse proxying)。这是因为web服务器会像代理服务器那样从远程服务器中抓取文档并将它们响应到客户端。 但是它与普通代理(normal(forward) proxy)不同的是,反向代理会让这些远程文档看起来就像是来源自反向代理服务器自身中一样,换句话说也就是隐藏了这些文档的真实来源。

在下面的例子中,当客户端请求位于/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 指令会让httpd调整在Location, Content-Location和URI 头信息中的URL,也就是将被代理站点发出的响应中的这三个头信息中的URL内容替换为反向代理站点。
ProxyPassReverseCookieDomain 调整set-cookie头信息中的domain内容。
ProxyPassReverseCookiePath 调整set-cookie头信息中的path内容。

非常值得注意的是: 在被代理的文档中的链接并不会被重写。所以任何绝对路径的链接最终还是会请求到被代理服务中去。更多相关的内容可以参考mod_substitute.和mod_proxy_html

注释: 说说我对正向代理的理解,比如我们无法直接访问外网,需要通过代理服务器来访问,那么客户端实际上会先将请求发送给代理,然后代理可能会再去访问请求中的目标,并将真实目标的响应回传到客户端,也可能利用自身的缓存(cache)直接响应给客户端。 无论哪种方式,客户端访问站点a,那么获得的响应文档也的确是来自站点a。我们在浏览器中配置的网络代理其实就是正向代理,如下图。 正向代理与反向代理的区别也就在这里:反向代理会隐藏文档的真正来源,而正向代理则不会

重写引擎(Rewriting Engine)

当我们需要更加强大的映射规则时,由mod_rewrite提供的重写引擎(rewriting engine)将会很有用。这个模块提供的指令可以利用请求诸如浏览器类型或者IP地址等特性来决定响应何种内容。更进一步,mod_rewrite模块可以使用外部的数据库文件或者程序来决定如何处理一个请求。重写引擎(rewriting engine)有能力处理以上讨论的全部三种映射规则:内部重定向(aliases)、外部重定向和代理。更多实际的例子可以访问 mod_rewrite documentation

Apache HTTP Server 映射URL到文件系统(翻译)的更多相关文章

  1. Apache HTTP Server应用的几个场景

    Apache HTTP Server应用的几个场景 前言 尽管Apache具有重量级.耗资源.低性能(相比其它的WebServer)的特点,但是同时它也具有兼容性强.稳定性高.模块丰富等特点,且处理动 ...

  2. Apache HTTP Server 虚拟主机配置

    Apache HTTP Server 虚拟主机配置(三)     什么是虚拟主机 "虚拟主机"是指在一个机器上运行多个网站(比如:www.company1.com  和 www.c ...

  3. 怎样从外网访问内网Apache HTTP Server

    本地安装了一个Apache HTTP Server,只能在局域网内访问,怎样从外网也能访问到本地的Apache HTTP Server呢?本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

  4. [转]Apache HTTP Server 与 Tomcat 的三种连接方式介绍

    首先我们先介绍一下为什么要让 Apache 与 Tomcat 之间进行连接.事实上 Tomcat 本身已经提供了 HTTP 服务,该服务默认的端口是 8080,装好 tomcat 后通过 8080 端 ...

  5. tomcat集群学习记录1--初识apache http server

    起因 平时开发的时候我都是用eclipse把代码部署到本地tomcat的,当然只会去跑1台tomcat啦... 偶尔有时候解决问题需要去公司测试环境找日志.连上公司测试环境以后发现竟然有2台weblo ...

  6. CentOS7安装配置Apache HTTP Server

    RPM安装httpd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # yum -yinstall http ...

  7. Windows 下 Apache HTTP Server 安装、配置以及与 Tomcat 的整合(附图)

    如果您能点开这篇文章,说明您已对熟悉Apache HTTP Server(下文用Apache简称)配置的重要性已很清楚了,本文不在赘述,直接介入正题,请往下阅读: 为便于阅读,列出文章目录: 一.Ap ...

  8. CentOS 7安装配置Apache HTTP Server

    原文 CentOS 7安装配置Apache HTTP Server   RPM安装httpd # yum -yinstall httpd //安装httpd会自动安装一下依赖包: apr apr-ut ...

  9. Django部署到Apache Web Server

    Windows环境下,将Django部署到Apache Web Server 在Windows上部署Django(用mod_wsgi)会出现各种奇怪的问题,现简单记录下配置过程及遇到的错误及解决方法. ...

随机推荐

  1. 记git提交异常

    描述:git项目工作目录和idea空间配置不一致导致git提交了其他项目至gitlab 项目a的工作目录设置为为a的父目录.提交时将目录下的 b项目提交至git 且提交时显示内容与实际提交不符 工作电 ...

  2. 前端Vscode常用插件概述

    以下是我自己在工作中常用的插件,写给刚入门的前端coder.VSCode插件商店中实用的插件还是很多的,大家也可以对感兴趣的插件下载下来尝试一下的! 持续更新 插件名称 概述 作用 常用默认快捷键 C ...

  3. jQuery是如何实现?

    jQuery是什么? jQuery就是一个javascript的类库,函数库. jQuery是如何实现的? jQuery采用的是构造函数模式进行开发的,jQuery是一个类 常用的方法(CSS.属性. ...

  4. SpringBoot+Prometheus+Grafana实现应用监控和报警

    一.背景 SpringBoot的应用监控方案比较多,SpringBoot+Prometheus+Grafana是目前比较常用的方案之一.它们三者之间的关系大概如下图: 关系图 二.开发SpringBo ...

  5. 8. 格式化器大一统 -- Spring的Formatter抽象

    目录 ✍前言 本文提纲 版本约定 ✍正文 Printer&Parser Formatter 时间日期格式化 Date类型 代码示例 JSR 310类型 整合DateTimeFormatter ...

  6. vs code编写java

    不知不觉中vs code变得非常强大了,今天小编就分享一下vs code编写java语言.其实除了java语言,还支持很多语言. 首先看下vs code欢迎页面支持哪些语言: 好家伙,支持的东西还真不 ...

  7. Lesson_strange_words1

    time-between system 分时操作:分时系统 secondary 辅助的,从属的 establish 已确立的 capability 功能 formerly 之前的 combine 结合 ...

  8. epoll的陷阱实践

    在使用epoll的时候,我们上篇文章epoll的陷阱大体介绍了epoll中会有哪些问题.这篇文章我们就针对必须要了解,也是绕不过去的陷阱进行实验,看看现象是什么,并且如何编写才能达到我们想要的效果. ...

  9. Go从入门到放弃(笔记存档)

    前言 考虑到印象笔记以后不续费了,这里转存到博客园一份 因内容是自己写的笔记, 未作任何润色, 所以看着很精简, 请见谅 查看官方文档 在新的go安装包中,为了减小体积默认去除了go doc 安装go ...

  10. Openstack OCATA 安装环境说明(一) 未完成版本

    1 Openstack简介: 2 实验说明: 3 图例: 4 实验环境说明: 4.1 ) 网卡说明: 网卡名 网 段 连接方式 说明 eth0 10.10.5.0/24 仅主机网络 内部网络自动以IP ...