Apache 静态资源服务 #

静态资源服务概述 #

什么是静态资源服务? #

text
┌─────────────────────────────────────────────────────────────┐
│                    静态资源服务                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   静态资源:不需要服务器处理,直接返回给客户端的文件          │
│                                                             │
│   常见静态资源类型:                                         │
│   ├── HTML 文件        .html, .htm                         │
│   ├── CSS 样式表       .css                                │
│   ├── JavaScript       .js                                 │
│   ├── 图片文件         .jpg, .png, .gif, .svg, .webp       │
│   ├── 字体文件         .woff, .woff2, .ttf, .eot           │
│   ├── 视频文件         .mp4, .webm, .ogg                   │
│   ├── 音频文件         .mp3, .wav, .ogg                    │
│   ├── 文档文件         .pdf, .doc, .xls                    │
│   └── 其他文件         .json, .xml, .txt                   │
│                                                             │
│   Apache 处理流程:                                         │
│   客户端请求 ──> Apache ──> 查找文件 ──> 直接返回           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基础配置 #

设置文档根目录 #

apache
# ============================================
# 文档根目录配置
# ============================================

# 设置网站根目录
DocumentRoot /var/www/html

# 配置根目录权限
<Directory /var/www/html>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

目录选项详解 #

apache
# ============================================
# Options 指令详解
# ============================================

<Directory /var/www/html>
    # Indexes - 目录列表
    # 当没有默认首页时,显示目录内容列表
    Options +Indexes
    
    # FollowSymLinks - 跟随符号链接
    # 允许访问符号链接指向的文件
    Options +FollowSymLinks
    
    # SymLinksIfOwnerMatch - 条件符号链接
    # 仅当链接所有者与目标所有者相同时才跟随
    Options +SymLinksIfOwnerMatch
    
    # ExecCGI - 执行 CGI 脚本
    # 允许执行 CGI 程序
    Options +ExecCGI
    
    # Includes - SSI 支持
    # 启用服务器端包含
    Options +Includes
    
    # MultiViews - 内容协商
    # 根据客户端偏好选择合适版本
    Options +MultiViews
    
    # All - 启用所有选项
    Options All
    
    # None - 禁用所有选项
    Options None
    
    # 组合使用(推荐)
    Options -Indexes +FollowSymLinks
    # - 前缀表示禁用
    # + 前缀表示启用
</Directory>

默认首页配置 #

apache
# ============================================
# DirectoryIndex 默认首页
# ============================================

# 设置默认首页文件(按顺序查找)
DirectoryIndex index.html index.php index.htm

# 在虚拟主机中设置
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example
    
    <Directory /var/www/example>
        DirectoryIndex index.html index.php
    </Directory>
</VirtualHost>

# 多个默认首页(优先级从左到右)
DirectoryIndex index.html index.htm index.php default.html

# 动态生成首页
DirectoryIndex index.php index.html

目录浏览 #

启用目录浏览 #

apache
# ============================================
# 目录浏览配置
# ============================================

# 启用目录列表
<Directory /var/www/html/files>
    Options +Indexes
    # 没有默认首页时显示目录内容
</Directory>

# 自定义目录列表样式
<Directory /var/www/html/files>
    Options +Indexes
    
    # 显示文件图标
    IndexOptions FancyIndexing
    
    # 显示文件描述
    IndexOptions HTMLTable
    
    # 显示文件大小和修改时间
    IndexOptions FoldersFirst
    
    # 设置图标
    IndexOptions IconsAreLinks
    
    # 设置列宽
    IndexOptions NameWidth=50 DescriptionWidth=50
    
    # 忽略隐藏文件
    IndexIgnore .ht* *.bak *.log
    
    # 添加描述
    AddDescription "HTML文档" .html .htm
    AddDescription "图片文件" .jpg .png .gif
    AddDescription "压缩文件" .zip .tar .gz
    AddDescription "PDF文档" .pdf
</Directory>

目录浏览示例 #

apache
# 完整的目录浏览配置示例
Alias /downloads /var/www/downloads

<Directory /var/www/downloads>
    Options +Indexes +FollowSymLinks
    AllowOverride None
    Require all granted
    
    IndexOptions FancyIndexing HTMLTable FoldersFirst
    
    IndexIgnore .ht* *.log
    
    AddDescription "HTML文档" .html .htm
    AddDescription "CSS样式" .css
    AddDescription "JavaScript" .js
    AddDescription "图片文件" .jpg .jpeg .png .gif .svg
    AddDescription "压缩文件" .zip .tar .gz .rar
    AddDescription "PDF文档" .pdf
    AddDescription "Word文档" .doc .docx
    AddDescription "Excel表格" .xls .xlsx
    
    # 设置图标
    AddIcon /icons/text.gif .html .htm .css .js
    AddIcon /icons/image.gif .jpg .png .gif .svg
    AddIcon /icons/compressed.gif .zip .tar .gz .rar
    AddIcon /icons/pdf.gif .pdf
</Directory>

禁用目录浏览 #

apache
# 禁用目录浏览(推荐用于生产环境)
<Directory /var/www/html>
    Options -Indexes
    # 没有默认首页时返回 403 Forbidden
</Directory>

# 或使用 .htaccess
# .htaccess 文件
Options -Indexes

MIME 类型配置 #

MIME 类型基础 #

text
┌─────────────────────────────────────────────────────────────┐
│                    MIME 类型                                 │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  MIME 类型告诉浏览器如何处理文件                             │
│                                                             │
│  格式:类型/子类型                                          │
│                                                             │
│  常见 MIME 类型:                                           │
│  ├── text/html          HTML 文档                          │
│  ├── text/css           CSS 样式表                         │
│  ├── text/javascript    JavaScript                        │
│  ├── application/json   JSON 数据                         │
│  ├── application/pdf    PDF 文档                          │
│  ├── image/jpeg         JPEG 图片                         │
│  ├── image/png          PNG 图片                          │
│  ├── video/mp4          MP4 视频                          │
│  └── audio/mpeg         MP3 音频                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

配置 MIME 类型 #

apache
# ============================================
# MIME 类型配置
# ============================================

# 加载 MIME 类型配置文件
TypesConfig /etc/mime.types

# 添加 MIME 类型
AddType text/html .html .htm
AddType text/css .css
AddType text/javascript .js
AddType application/json .json
AddType application/xml .xml
AddType application/pdf .pdf

# 图片类型
AddType image/jpeg .jpg .jpeg
AddType image/png .png
AddType image/gif .gif
AddType image/svg+xml .svg .svgz
AddType image/webp .webp
AddType image/x-icon .ico

# 字体类型
AddType font/woff .woff
AddType font/woff2 .woff2
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf

# 视频类型
AddType video/mp4 .mp4
AddType video/webm .webm
AddType video/ogg .ogv

# 音频类型
AddType audio/mpeg .mp3
AddType audio/ogg .ogg
AddType audio/wav .wav

# 压缩文件
AddType application/zip .zip
AddType application/x-gzip .gz .tgz
AddType application/x-rar-compressed .rar

# 文档类型
AddType application/msword .doc
AddType application/vnd.openxmlformats-officedocument.wordprocessingml.document .docx
AddType application/vnd.ms-excel .xls
AddType application/vnd.openxmlformats-officedocument.spreadsheetml.sheet .xlsx

字符编码配置 #

apache
# ============================================
# 字符编码配置
# ============================================

# 默认字符编码
AddDefaultCharset UTF-8

# 特定文件类型的编码
AddCharset UTF-8 .html .css .js .json .xml

# 在虚拟主机中设置
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example
    
    AddDefaultCharset UTF-8
    
    <Directory /var/www/example>
        AddCharset UTF-8 .html .htm .css .js
    </Directory>
</VirtualHost>

文件权限与访问控制 #

文件系统权限 #

bash
# ============================================
# 设置文件系统权限
# ============================================

# 设置目录所有者
sudo chown -R www-data:www-data /var/www/html    # Ubuntu/Debian
sudo chown -R apache:apache /var/www/html        # CentOS/RHEL

# 设置目录权限
sudo find /var/www/html -type d -exec chmod 755 {} \;

# 设置文件权限
sudo find /var/www/html -type f -exec chmod 644 {} \;

# 特殊权限设置
# 可写目录(上传目录等)
sudo chmod 755 /var/www/html/uploads

# 可执行文件
sudo chmod 755 /var/www/html/cgi-bin/script.cgi

Apache 访问控制 #

apache
# ============================================
# 访问控制配置
# ============================================

# 允许所有访问
<Directory /var/www/html>
    Require all granted
</Directory>

# 拒绝所有访问
<Directory /var/www/html/private>
    Require all denied
</Directory>

# 仅允许特定 IP
<Directory /var/www/html/admin>
    Require ip 192.168.1.0/24
</Directory>

# 允许多个 IP 段
<Directory /var/www/html/internal>
    Require ip 192.168.1.0/24
    Require ip 10.0.0.0/8
    Require ip 172.16.0.0/12
</Directory>

# 排除特定 IP
<Directory /var/www/html/public>
    <RequireAll>
        Require all granted
        Require not ip 192.168.1.100
    </RequireAll>
</Directory>

# 文件级别访问控制
<Files ".ht*">
    Require all denied
</Files>

<Files "config.php">
    Require ip 192.168.1.0/24
</Files>

<FilesMatch "\.(log|bak|sql)$">
    Require all denied
</FilesMatch>

别名配置 #

Alias 指令 #

apache
# ============================================
# URL 别名配置
# ============================================

# 简单别名
Alias /images /var/www/images
Alias /downloads /var/www/downloads
Alias /docs /usr/share/doc

# 带权限配置的别名
Alias /icons /usr/share/apache2/icons

<Directory /usr/share/apache2/icons>
    Options Indexes MultiViews
    AllowOverride None
    Require all granted
</Directory>

# URL 重定向别名
Alias /old-path /var/www/new-path

# 正则表达式别名
AliasMatch ^/icons/(.*) /usr/share/apache2/icons/$1
AliasMatch ^/user/([0-9]+) /var/www/users/profile.php?id=$1

ScriptAlias 配置 #

apache
# ============================================
# CGI 脚本别名
# ============================================

# CGI 脚本目录
ScriptAlias /cgi-bin/ /var/www/cgi-bin/

<Directory /var/www/cgi-bin>
    Options +ExecCGI
    SetHandler cgi-script
    Require all granted
</Directory>

# 添加 CGI 处理
AddHandler cgi-script .cgi .pl .py

文件上传配置 #

上传目录配置 #

apache
# ============================================
# 文件上传目录配置
# ============================================

# 上传目录
Alias /uploads /var/www/uploads

<Directory /var/www/uploads>
    Options -Indexes -FollowSymLinks
    AllowOverride None
    Require all granted
    
    # 禁止执行脚本
    php_flag engine off
    
    # 限制文件类型
    <FilesMatch "\.(php|phtml|php3|php4|php5|php7|phps)$">
        Require all denied
    </FilesMatch>
    
    # 设置上传限制
    LimitRequestBody 10485760    # 10MB
</Directory>

上传限制配置 #

apache
# ============================================
# 上传限制配置
# ============================================

# 限制请求体大小
LimitRequestBody 10485760    # 10MB

# 限制请求头数量
LimitRequestFields 50

# 限制请求行长度
LimitRequestLine 8190

# 限制请求头大小
LimitRequestFieldSize 8190

# 在虚拟主机中配置
<VirtualHost *:80>
    ServerName upload.example.com
    DocumentRoot /var/www/upload
    
    <Directory /var/www/upload>
        LimitRequestBody 104857600    # 100MB
    </Directory>
</VirtualHost>

静态资源优化 #

启用压缩 #

apache
# ============================================
# Gzip 压缩配置
# ============================================

# 加载模块
LoadModule deflate_module modules/mod_deflate.so

# 压缩配置
<IfModule mod_deflate.c>
    # 压缩级别(1-9)
    DeflateCompressionLevel 6
    
    # 压缩类型
    AddOutputFilterByType DEFLATE text/html text/plain text/xml
    AddOutputFilterByType DEFLATE text/css text/javascript
    AddOutputFilterByType DEFLATE application/javascript application/x-javascript
    AddOutputFilterByType DEFLATE application/json application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml application/rss+xml
    
    # 排除不压缩的文件类型
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip
    SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip
    SetEnvIfNoCase Request_URI \.(?:pdf|mov|avi|mp3|mp4|rm)$ no-gzip
    
    # 代理服务器处理
    DeflateFilterNote Input instream
    DeflateFilterNote Output outstream
    DeflateFilterNote Ratio ratio
</IfModule>

缓存配置 #

apache
# ============================================
# 浏览器缓存配置
# ============================================

# 加载模块
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so

# Expires 配置
<IfModule mod_expires.c>
    ExpiresActive On
    
    # 默认缓存时间
    ExpiresDefault "access plus 1 month"
    
    # HTML 文件
    ExpiresByType text/html "access plus 1 hour"
    
    # CSS 和 JavaScript
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType text/javascript "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    
    # 图片文件
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"
    
    # 字体文件
    ExpiresByType font/woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    
    # 视频和音频
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType audio/mpeg "access plus 1 year"
</IfModule>

# Cache-Control 头
<IfModule mod_headers.c>
    # HTML 不缓存
    <FilesMatch "\.(html|htm)$">
        Header set Cache-Control "no-cache, no-store, must-revalidate"
        Header set Pragma "no-cache"
        Header set Expires 0
    </FilesMatch>
    
    # 静态资源强缓存
    <FilesMatch "\.(css|js|jpg|jpeg|png|gif|svg|woff|woff2)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
</IfModule>

ETag 配置 #

apache
# ============================================
# ETag 配置
# ============================================

# 启用 ETag
FileETag MTime Size

# 或使用 INode MTime Size
# FileETag INode MTime Size

# 禁用 ETag(如果使用 Last-Modified)
# FileETag None

# 为静态资源设置 ETag
<Directory /var/www/html/static>
    FileETag MTime Size
</Directory>

安全配置 #

隐藏敏感文件 #

apache
# ============================================
# 隐藏敏感文件
# ============================================

# 禁止访问隐藏文件
<FilesMatch "^\.">
    Require all denied
</FilesMatch>

# 禁止访问备份文件
<FilesMatch "~$">
    Require all denied
</FilesMatch>

# 禁止访问配置文件
<FilesMatch "\.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)$">
    Require all denied
</FilesMatch>

# 禁止访问特定文件
<FilesMatch "(^\.ht|\.git|\.svn|\.env)">
    Require all denied
</FilesMatch>

# 禁止访问版本控制目录
RedirectMatch 404 /\.git
RedirectMatch 404 /\.svn
RedirectMatch 404 /\.env

防盗链配置 #

apache
# ============================================
# 防盗链配置
# ============================================

# 启用 rewrite 模块
LoadModule rewrite_module modules/mod_rewrite.so

<IfModule mod_rewrite.c>
    RewriteEngine On
    
    # 图片防盗链
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://(www\.)?example\.com/ [NC]
    RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com/ [NC]
    RewriteCond %{HTTP_REFERER} !^http://(www\.)?trusted\.com/ [NC]
    RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F,NC,L]
    
    # 或返回替代图片
    # RewriteRule \.(jpg|jpeg|png|gif)$ /images/hotlink.png [NC,L]
</IfModule>

# 使用 SetEnvIf 方式
SetEnvIfNoCase Referer "^http://(www\.)?example\.com/" local_ref=1
SetEnvIfNoCase Referer "^https://(www\.)?example\.com/" local_ref=1
SetEnvIfNoCase Referer "^$" local_ref=1

<FilesMatch "\.(jpg|jpeg|png|gif|webp)$">
    Order Allow,Deny
    Allow from env=local_ref
</FilesMatch>

限制文件访问 #

apache
# ============================================
# 限制文件访问
# ============================================

# 限制访问特定目录
<Directory /var/www/html/private>
    Require ip 192.168.1.0/24
</Directory>

# 限制访问配置文件
<FilesMatch "\.(conf|cfg|ini|log)$">
    Require ip 192.168.1.0/24
</FilesMatch>

# 禁止访问上传目录中的脚本
<Directory /var/www/html/uploads>
    <FilesMatch "\.(php|phtml|php3|php4|php5|php7)$">
        Require all denied
    </FilesMatch>
</Directory>

# 限制请求方法
<Directory /var/www/html/static>
    <LimitExcept GET HEAD OPTIONS>
        Require all denied
    </LimitExcept>
</Directory>

完整配置示例 #

静态网站配置 #

apache
# ============================================
# 静态网站完整配置
# ============================================

<VirtualHost *:80>
    ServerName static.example.com
    ServerAdmin webmaster@example.com
    DocumentRoot /var/www/static
    
    # 日志配置
    ErrorLog ${APACHE_LOG_DIR}/static-error.log
    CustomLog ${APACHE_LOG_DIR}/static-access.log combined
    
    # 目录配置
    <Directory /var/www/static>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
        
        DirectoryIndex index.html index.htm
    </Directory>
    
    # 静态资源缓存
    <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresByType text/css "access plus 1 year"
        ExpiresByType application/javascript "access plus 1 year"
        ExpiresByType image/jpeg "access plus 1 year"
        ExpiresByType image/png "access plus 1 year"
        ExpiresByType image/gif "access plus 1 year"
        ExpiresByType image/svg+xml "access plus 1 year"
    </IfModule>
    
    # Gzip 压缩
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/html text/css application/javascript
    </IfModule>
    
    # 安全配置
    <FilesMatch "^\.">
        Require all denied
    </FilesMatch>
    
    # 隐藏服务器信息
    ServerSignature Off
    ServerTokens Prod
</VirtualHost>

文件下载服务器配置 #

apache
# ============================================
# 文件下载服务器配置
# ============================================

<VirtualHost *:80>
    ServerName download.example.com
    DocumentRoot /var/www/downloads
    
    # 启用目录浏览
    <Directory /var/www/downloads>
        Options +Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
        
        IndexOptions FancyIndexing HTMLTable FoldersFirst NameWidth=*
        IndexIgnore .ht* *.log
        
        AddDescription "压缩文件" .zip .tar .gz .rar
        AddDescription "文档文件" .pdf .doc .docx .xls .xlsx
        AddDescription "安装包" .deb .rpm .exe .dmg
    </Directory>
    
    # 限制下载速度(需要 mod_ratelimit)
    <Location />
        SetOutputFilter RATE_LIMIT
        LimitRate 102400    # 100KB/s
    </Location>
    
    # 日志
    ErrorLog ${APACHE_LOG_DIR}/download-error.log
    CustomLog ${APACHE_LOG_DIR}/download-access.log combined
</VirtualHost>

下一步 #

掌握了静态资源服务配置后,继续学习 虚拟主机配置,了解如何在一台服务器上托管多个网站!

最后更新:2026-03-29