Claude---Project_DatabaseAgain----url重定向可以运行版本-----只修改httpd.conf技术文档总结

# Apache URL重写实现CGI路径美化 - 完整技术文档

## 1. 功能实现

### ✅ 核心功能

**实现效果**:
- **隐藏 `/cgi-bin/` 目录**:用户看不到技术细节路径
- **隐藏 `.cgi` 扩展名**:URL更简洁美观
- **自动重定向**:访问旧URL自动跳转到新URL
- **透明执行**:后台正常执行CGI程序

**具体转换**:

| 原始URL | 浏览器显示URL | 实际执行 |
|---------|--------------|---------|
| `/cgi-bin/Artocarpus/searchGenome.cgi` | `/Artocarpus/searchGenome` | `/var/www/cgi-bin/Artocarpus/searchGenome.cgi` |
| `/cgi-bin/searchAnnotationAGD.cgi` | `/searchAnnotationAGD` | `/var/www/cgi-bin/searchAnnotationAGD.cgi` |
| `/go_carica.cgi?job_id=123` | `/go_carica?job_id=123` | `/var/www/cgi-bin/go_carica.cgi` |

### ✅ 附加功能

1. **参数保留**:所有URL查询参数(`?key=value`)完整传递
2. **静态文件保护**:HTML/CSS/JS/图片等不受影响
3. **向后兼容**:旧链接自动重定向,不会失效
4. **零代码修改**:不需要修改任何CGI或HTML文件

---

## 2. 方法缺点与性能影响

### ⚠️ 主要缺点

#### **性能开销**
- **延迟增加**:20-100ms(通常约50ms)
- **原因**:每次访问需要1次额外的HTTP重定向
- **流程**:
  ```
  用户点击 → 浏览器请求旧URL → 服务器返回307重定向 (往返1)
           → 浏览器请求新URL → 服务器执行CGI (往返2)
  ```
- **影响评估**:
  - 如果CGI执行时间 > 1秒(数据库查询等),50ms增加约**3-5%开销**,几乎可忽略
  - 如果CGI执行时间 < 100ms(快速响应),50ms增加约**50%开销**,比较明显

#### **服务器负载**
- 每次请求变成2次HTTP处理(重定向 + 实际执行)
- 高并发时服务器压力增加约**2倍**

#### **配置复杂性**
- 需要维护复杂的重写规则
- 添加新CGI目录需要添加对应规则
- 调试困难(需要查看重写日志)

### 💡 优化建议

**如果追求最佳性能**,应该:
1. **修改HTML文件中的链接**(改为 `/Artocarpus/searchGenome`)
2. **简化Apache配置**(只保留内部重写,去掉重定向规则)
3. **结果**:零性能损失

---

## 3. 配置规则详细说明

### 📋 规则架构总览

```
外部重定向规则(4条)→ 修改浏览器地址栏
    ↓
内部重写规则(2条)→ 后台执行CGI
```

---

### **规则1a:Artocarpus子目录CGI重定向**

```apache
RewriteRule ^/cgi-bin/Artocarpus/(.+)\.cgi$ /Artocarpus/$1 [R=307,L,QSA]
```

**功能**:处理Artocarpus子目录下的CGI访问  
**匹配**:`/cgi-bin/Artocarpus/任意文件名.cgi`  
**重定向到**:`/Artocarpus/文件名`(去掉路径和扩展名)

**语法说明**:
- `^` - 行首锚点
- `/cgi-bin/Artocarpus/` - 字面匹配路径
- `(.+)` - 捕获组1:匹配1个或多个任意字符(文件名)
- `\.cgi` - 匹配 `.cgi`(反斜杠转义点号)
- `$` - 行尾锚点
- `$1` - 引用捕获组1的内容

**标志说明**:
- `R=307` - 临时重定向(保持POST方法)
- `L` - Last,停止处理后续规则
- `QSA` - Query String Append,保留URL参数

**示例**:
```
/cgi-bin/Artocarpus/searchGenome.cgi?id=123
  ↓
/Artocarpus/searchGenome?id=123
```

---

### **规则1b:Artocarpus目录直接访问.cgi重定向**

```apache
RewriteRule ^/Artocarpus/(.+)\.cgi$ /Artocarpus/$1 [R=307,L,QSA]
```

**功能**:处理直接访问 `/Artocarpus/*.cgi` 的情况  
**原因**:有些链接可能直接指向 `/Artocarpus/xxx.cgi`(不通过 `/cgi-bin/`)

**匹配**:`/Artocarpus/任意文件名.cgi`  
**重定向到**:`/Artocarpus/文件名`

**示例**:
```
/Artocarpus/searchmRNA.cgi?sp=ArNa
  ↓
/Artocarpus/searchmRNA?sp=ArNa
```

---

### **规则1c:根目录CGI重定向(通过cgi-bin)**

```apache
RewriteRule ^/cgi-bin/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
```

**功能**:处理根目录CGI访问(通过 `/cgi-bin/` 路径)  
**关键**:`[^/]+` 确保只匹配单层文件名,不匹配包含 `/` 的路径

**匹配**:`/cgi-bin/文件名.cgi`(文件名中不能包含 `/`)  
**重定向到**:`/文件名`

**语法说明**:
- `[^/]+` - 字符类:匹配1个或多个**非斜杠**字符
- 这样 `/cgi-bin/Artocarpus/xxx.cgi` **不会**匹配(因为包含 `/`)
- 只匹配 `/cgi-bin/searchAnnotationAGD.cgi` 这种根目录文件

**示例**:
```
/cgi-bin/searchAnnotationAGD.cgi
  ↓
/searchAnnotationAGD

/cgi-bin/Artocarpus/searchGenome.cgi
  ✗ 不匹配(被规则1a处理)
```

---

### **规则1d:根目录直接访问.cgi重定向**

```apache
RewriteCond %{REQUEST_URI} !^/Artocarpus/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteRule ^/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
```

**功能**:处理直接访问 `/*.cgi` 的情况  
**关键**:需要排除 `/Artocarpus/` 和 `/cgi-bin/` 路径,避免冲突

**匹配**:`/文件名.cgi`(根目录,不在Artocarpus或cgi-bin下)  
**重定向到**:`/文件名`

**RewriteCond说明**:
- `%{REQUEST_URI}` - 当前请求的URI
- `!^/Artocarpus/` - 不以 `/Artocarpus/` 开头(感叹号表示否定)
- `!^/cgi-bin/` - 不以 `/cgi-bin/` 开头

**为什么需要这些条件**?
- 防止与规则1a、1b冲突
- 确保只处理根目录的 `.cgi` 文件

**示例**:
```
/go_carica.cgi?job_id=123
  ↓
/go_carica?job_id=123

/Artocarpus/searchGenome.cgi
  ✗ 不匹配(被规则1b处理)
```

---

### **规则2:Artocarpus目录内部重写**

```apache
RewriteCond %{REQUEST_URI} !\.htm$
RewriteCond %{REQUEST_URI} !\.html$
RewriteCond %{REQUEST_URI} !\.css$
RewriteCond %{REQUEST_URI} !\.js$
RewriteCond %{REQUEST_URI} !\.png$
RewriteCond %{REQUEST_URI} !\.jpg$
RewriteCond %{REQUEST_URI} !\.gif$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/Artocarpus/([^/]+)$ /var/www/cgi-bin/Artocarpus/$1.cgi [L,QSA]
```

**功能**:将简洁URL(`/Artocarpus/searchGenome`)内部重写到实际CGI路径  
**关键**:这是**内部重写**,浏览器地址栏不变,只在服务器内部执行

**工作流程**:
```
浏览器显示:/Artocarpus/searchGenome
     ↓ (内部重写,浏览器不知道)
实际执行:/var/www/cgi-bin/Artocarpus/searchGenome.cgi
```

**RewriteCond详解**:

1. **排除静态文件**(前7条):
   ```apache
   RewriteCond %{REQUEST_URI} !\.htm$
   ```
   - 确保HTML、CSS、JS、图片等静态文件不被当作CGI处理
   - `$` 表示行尾,确保扩展名在末尾

2. **文件/目录存在性检查**:
   ```apache
   RewriteCond %{REQUEST_FILENAME} !-f  # 文件不存在
   RewriteCond %{REQUEST_FILENAME} !-d  # 目录不存在
   ```
   - 如果 `/var/www/html/Artocarpus/searchGenome` 文件存在,则不重写
   - 保护现有静态文件不被覆盖

**RewriteRule说明**:
- `^/Artocarpus/([^/]+)$` - 匹配 `/Artocarpus/单层文件名`
- `[^/]+` - 不包含斜杠,确保只匹配单层路径
- `/var/www/cgi-bin/Artocarpus/$1.cgi` - 重写到实际CGI路径
- **无 `R` 标志** - 内部重写,不重定向

**示例**:
```
请求:/Artocarpus/searchGenome
内部重写到:/var/www/cgi-bin/Artocarpus/searchGenome.cgi
浏览器地址栏:/Artocarpus/searchGenome(不变)
```

---

### **规则3:根目录内部重写**

```apache
RewriteCond %{REQUEST_URI} !\.htm$
RewriteCond %{REQUEST_URI} !\.html$
RewriteCond %{REQUEST_URI} !\.css$
RewriteCond %{REQUEST_URI} !\.js$
RewriteCond %{REQUEST_URI} !\.png$
RewriteCond %{REQUEST_URI} !\.jpg$
RewriteCond %{REQUEST_URI} !\.gif$
RewriteCond %{REQUEST_URI} !\.ico$
RewriteCond %{REQUEST_URI} !^/Artocarpus/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/[^/]+$
RewriteRule ^/([^/]+)$ /var/www/cgi-bin/$1.cgi [L,QSA]
```

**功能**:将根目录简洁URL(`/searchAnnotationAGD`)内部重写到实际CGI  
**关键**:与规则2类似,但针对根目录,需要更多保护条件

**额外的RewriteCond**:
```apache
RewriteCond %{REQUEST_URI} !^/Artocarpus/  # 排除Artocarpus路径
RewriteCond %{REQUEST_URI} !^/cgi-bin/     # 排除cgi-bin路径
RewriteCond %{REQUEST_URI} ^/[^/]+$        # 只匹配单层路径
```

**为什么需要 `^/[^/]+$`**?
- 确保只匹配 `/filename` 格式
- 不匹配 `/path/to/file` 多层路径
- 不匹配 `/` 根路径

**示例**:
```
请求:/searchAnnotationAGD?param=test
内部重写到:/var/www/cgi-bin/searchAnnotationAGD.cgi
浏览器地址栏:/searchAnnotationAGD?param=test(不变)

请求:/some/path/file
  ✗ 不匹配(包含多层路径)
```

---

## 4. 易错点与注意事项

### ⚠️ 关键易错点

#### **1. 规则顺序至关重要**

```apache
# ✅ 正确顺序
规则1a: /cgi-bin/Artocarpus/*.cgi  (最具体)
规则1b: /Artocarpus/*.cgi
规则1c: /cgi-bin/*.cgi            (较通用)
规则1d: /*.cgi                     (最通用)
规则2:  /Artocarpus/* 内部重写
规则3:  /* 内部重写
```

**原因**:Apache从上到下匹配,遇到 `[L]` 标志就停止。如果把通用规则放前面,具体规则永远不会执行。

**错误示例**:
```apache
# ❌ 错误:通用规则在前
RewriteRule ^/cgi-bin/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
RewriteRule ^/cgi-bin/Artocarpus/(.+)\.cgi$ /Artocarpus/$1 [R=307,L,QSA]
# 结果:第二条规则永远不会执行!
```

---

#### **2. 字符类 `[^/]` vs `.+` 的区别**

```apache
# 规则1c:只匹配单层文件名
RewriteRule ^/cgi-bin/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
匹配: /cgi-bin/file.cgi ✅
不匹配: /cgi-bin/dir/file.cgi ❌

# 如果错误地使用 .+
RewriteRule ^/cgi-bin/(.+)\.cgi$ /$1 [R=307,L,QSA]
匹配: /cgi-bin/file.cgi ✅
匹配: /cgi-bin/dir/file.cgi ✅ (冲突!)
```

**教训**:使用 `[^/]+` 来限制只匹配单层路径,避免冲突。

---

#### **3. RewriteCond 的否定条件容易遗漏**

```apache
# ❌ 错误:没有排除条件
RewriteRule ^/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
# 结果:/Artocarpus/file.cgi 也会匹配,导致冲突!

# ✅ 正确:添加排除条件
RewriteCond %{REQUEST_URI} !^/Artocarpus/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteRule ^/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
```

---

#### **4. 静态文件扩展名必须完整列出**

```apache
RewriteCond %{REQUEST_URI} !\.htm$
RewriteCond %{REQUEST_URI} !\.html$
RewriteCond %{REQUEST_URI} !\.css$
# ... 必须列出所有静态文件类型
```

**常见遗漏**:
- `.ico` (favicon)
- `.svg` (矢量图)
- `.pdf` (文档)
- `.txt` (文本)
- `.xml` (数据)

**如果遗漏**:这些文件会被当作CGI处理,导致404错误。

---

#### **5. 点号必须转义**

```apache
# ❌ 错误:点号未转义(匹配任意字符)
RewriteRule ^/file.cgi$ /file [R=307,L]

# ✅ 正确:点号转义
RewriteRule ^/file\.cgi$ /file [R=307,L]
```

**为什么**:在正则表达式中,`.` 匹配任意字符,`\.` 才匹配字面点号。

---

#### **6. QSA标志容易遗忘**

```apache
# ❌ 没有QSA:查询参数丢失
RewriteRule ^/cgi-bin/(.+)\.cgi$ /$1 [R=307,L]
# /cgi-bin/file.cgi?id=123 → /file (参数丢失!)

# ✅ 有QSA:查询参数保留
RewriteRule ^/cgi-bin/(.+)\.cgi$ /$1 [R=307,L,QSA]
# /cgi-bin/file.cgi?id=123 → /file?id=123 ✅
```

---

#### **7. REQUEST_FILENAME vs REQUEST_URI 的区别**

```apache
# REQUEST_URI:URL路径
%{REQUEST_URI} = "/Artocarpus/searchGenome"

# REQUEST_FILENAME:文件系统路径
%{REQUEST_FILENAME} = "/var/www/html/Artocarpus/searchGenome"
```

**用途**:
- 检查URL模式 → 用 `REQUEST_URI`
- 检查文件是否存在 → 用 `REQUEST_FILENAME`

---

## 5. 实现原理简介

### 📐 核心原理:双层处理机制

```
┌─────────────────────────────────────────────────────┐
│  用户访问: /cgi-bin/Artocarpus/searchGenome.cgi     │
└─────────────────┬───────────────────────────────────┘
                  │
                  ▼
         ┌────────────────────┐
         │  规则1a 匹配       │
         │  外部重定向 (307)  │
         └────────┬───────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────┐
│  浏览器收到: Location: /Artocarpus/searchGenome     │
│  浏览器地址栏变为: /Artocarpus/searchGenome         │
└─────────────────┬───────────────────────────────────┘
                  │
                  ▼
         ┌────────────────────┐
         │  浏览器发起新请求  │
         │  /Artocarpus/searchGenome  │
         └────────┬───────────┘
                  │
                  ▼
         ┌────────────────────┐
         │  规则2 匹配        │
         │  内部重写(透明)  │
         └────────┬───────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────┐
│  Apache内部执行:                                     │
│  /var/www/cgi-bin/Artocarpus/searchGenome.cgi       │
│  浏览器不知道,地址栏保持不变                       │
└─────────────────────────────────────────────────────┘
```

### 🔑 关键技术点

1. **外部重定向(R=307)**:
   - 告诉浏览器"你访问的URL变了,请访问新URL"
   - 浏览器地址栏会更新
   - 需要1次额外的HTTP往返

2. **内部重写(无R标志)**:
   - 在Apache内部修改请求路径
   - 浏览器完全不知道
   - 地址栏保持不变
   - 无性能损失

3. **PT标志的困境**:
   - 理论上 `PT`(Pass Through)应该让重写后的URL继续被ScriptAlias处理
   - 实际测试中 `PT` 在您的环境不工作(pass through但不执行)
   - 解决方案:直接重写到文件系统路径(`/var/www/cgi-bin/...`)

---

## 6. 扩展与维护指南

### 📌 添加新CGI程序的注意事项

#### **情况1:在现有目录添加CGI(最简单)**

```bash
# 在 /var/www/cgi-bin/Artocarpus/ 添加新CGI
touch /var/www/cgi-bin/Artocarpus/newScript.cgi
chmod +x /var/www/cgi-bin/Artocarpus/newScript.cgi
```

**✅ 无需修改配置**:现有规则1a、1b、规则2自动处理

**访问方式**:
- 旧URL:`/cgi-bin/Artocarpus/newScript.cgi` → 自动重定向
- 新URL:`/Artocarpus/newScript` → 直接访问

---

#### **情况2:在根目录添加CGI**

```bash
# 在 /var/www/cgi-bin/ 添加新CGI
touch /var/www/cgi-bin/newTool.cgi
chmod +x /var/www/cgi-bin/newTool.cgi
```

**✅ 无需修改配置**:现有规则1c、1d、规则3自动处理

**访问方式**:
- 旧URL:`/cgi-bin/newTool.cgi` → 自动重定向
- 新URL:`/newTool` → 直接访问

---

#### **情况3:添加新的子目录(需要修改配置)**

```bash
# 创建新目录
mkdir /var/www/cgi-bin/NewModule
touch /var/www/cgi-bin/NewModule/process.cgi
```

**⚠️ 需要添加规则**:

```apache
# 在规则1b后添加
# 规则1e: 新模块重定向
RewriteRule ^/cgi-bin/NewModule/(.+)\.cgi$ /NewModule/$1 [R=307,L,QSA]
RewriteRule ^/NewModule/(.+)\.cgi$ /NewModule/$1 [R=307,L,QSA]

# 在规则2后添加
# 规则4: 新模块内部重写
RewriteCond %{REQUEST_URI} !\.htm$
RewriteCond %{REQUEST_URI} !\.html$
# ... (复制所有静态文件排除条件)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/NewModule/([^/]+)$ /var/www/cgi-bin/NewModule/$1.cgi [L,QSA]

# 添加目录权限
<Directory "/var/www/cgi-bin/NewModule">
    Options +ExecCGI
    SetHandler cgi-script
    Require all granted
</Directory>
```

**规则顺序**:新规则应放在"更具体"的位置,即在通用规则之前。

---

### 🔍 正则表达式注意事项

#### **1. 文件名命名规范**

**推荐**:
```
✅ searchGenome.cgi      (驼峰命名)
✅ search_genome.cgi     (下划线)
✅ search-genome.cgi     (连字符)
✅ searchGenome123.cgi   (数字)
```

**避免**:
```
❌ search genome.cgi     (空格会导致URL编码问题)
❌ search/genome.cgi     (斜杠会被误解为路径)
❌ search.old.cgi        (多个点号可能引起混淆)
```

#### **2. 字符类使用**

```apache
[^/]+     # 匹配除斜杠外的任意字符(推荐用于文件名)
[^/\.]+   # 匹配除斜杠和点号外的任意字符
[a-zA-Z0-9_-]+  # 只匹配字母、数字、下划线、连字符(最严格)
.+        # 匹配任意字符(包括斜杠,慎用)
```

**推荐使用 `[^/]+`**:既灵活又安全。

#### **3. 锚点的重要性**

```apache
# ❌ 没有锚点:过度匹配
RewriteRule /cgi-bin/(.+)\.cgi /$1 [R=307,L,QSA]
# 会匹配: /some/path/with/cgi-bin/in/middle/file.cgi

# ✅ 有锚点:精确匹配
RewriteRule ^/cgi-bin/(.+)\.cgi$ /$1 [R=307,L,QSA]
# 只匹配: /cgi-bin/开头 且 .cgi结尾 的URL
```

**教训**:始终使用 `^` 和 `$` 锚点。

---

### 🛠️ 调试技巧

#### **1. 启用重写日志**

```apache
# 在VirtualHost中添加
LogLevel alert rewrite:trace6

# 重启Apache
sudo systemctl restart httpd

# 查看详细日志
sudo tail -f /var/log/httpd/morac_error.log | grep rewrite
```

**trace级别**:
- `trace1` - 最少信息
- `trace3` - 中等信息(推荐)
- `trace6` - 最详细信息

#### **2. 测试单条规则**

```bash
# 临时注释掉其他规则,只保留要测试的规则
# 然后测试
curl -I http://morac.ficusgd.com/test/path
```

#### **3. 使用 curl 的 -v 选项**

```bash
curl -v http://morac.ficusgd.com/cgi-bin/test.cgi 2>&1 | grep -E "(Location|HTTP)"
```

查看完整的HTTP头信息,包括重定向的Location。

---

### 📚 维护检查清单

定期检查(每季度或添加新功能时):

- [ ] 检查错误日志中是否有重写相关错误
- [ ] 测试所有重要的CGI是否正常访问
- [ ] 验证静态文件(HTML/CSS/JS)是否正常加载
- [ ] 测试带参数的URL是否正确传递参数
- [ ] 检查新添加的CGI是否被正确处理
- [ ] 确认规则顺序没有被意外改动

---

## 总结

这套配置实现了:
- ✅ **零代码修改**的URL美化方案
- ✅ **自动处理**现有和新增的CGI(在已配置目录下)
- ✅ **向后兼容**旧URL自动重定向
- ✅ **路径隔离**多个目录互不干扰

**性能代价**:每次访问增加约50ms延迟(1次重定向)

**适用场景**:
- 已有大量CGI脚本,不想修改代码
- 对50ms延迟可接受(数据库查询类应用)
- 需要向后兼容旧链接

**不适用场景**:
- 追求极致性能(< 100ms响应时间)
- 高并发(> 10000 req/s)

**最佳实践**:逐步迁移到修改HTML链接的方式,最终去掉重定向规则,只保留内部重写,实现零性能损失。

***************************************************************************************************
=================================================================================
***************************************************************************************************
#成功的httpd.conf添加于最后的配置规则(对应上文)
   # ======================================
473 # morac.ficusgd.com 站点配置
474 # 实现URL美化:隐藏 /cgi-bin/ 和 .cgi 后缀
475 # =====================================
476
477 #再次添加对/var/www/cgi-bin/下的cgi程序的url美化
478
479 <VirtualHost *:80>
480     ServerName morac.ficusgd.com
481     DocumentRoot /var/www/html
482
483     ScriptAlias /cgi-bin/ /var/www/cgi-bin/
484
485     RewriteEngine On
486
487     # 规则1a:重定向 /cgi-bin/Artocarpus/*.cgi
488     RewriteRule ^/cgi-bin/Artocarpus/(.+)\.cgi$ /Artocarpus/$1 [R=307,L,QSA]
489
490     # 规则1b:重定向 /Artocarpus/*.cgi(处理直接访问.cgi的情况)
491     RewriteRule ^/Artocarpus/(.+)\.cgi$ /Artocarpus/$1 [R=307,L,QSA]
492
493     # 规则1c:重定向 /cgi-bin/*.cgi → /*(只匹配根目录文件,不含路径)
494     RewriteRule ^/cgi-bin/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
495
496     # 规则1d:重定向 /*.cgi → /*(新增!处理直接访问根目录.cgi的情况)
497     RewriteCond %{REQUEST_URI} !^/Artocarpus/
498     RewriteCond %{REQUEST_URI} !^/cgi-bin/
499     RewriteRule ^/([^/]+)\.cgi$ /$1 [R=307,L,QSA]
500
501     # 规则2:内部重写 - 只处理不带扩展名的URL
502     RewriteCond %{REQUEST_URI} !\.htm$
503     RewriteCond %{REQUEST_URI} !\.html$
504     RewriteCond %{REQUEST_URI} !\.css$
505     RewriteCond %{REQUEST_URI} !\.js$
506     RewriteCond %{REQUEST_URI} !\.png$
507     RewriteCond %{REQUEST_URI} !\.jpg$
508     RewriteCond %{REQUEST_URI} !\.gif$
509     RewriteCond %{REQUEST_FILENAME} !-f
510     RewriteCond %{REQUEST_FILENAME} !-d
511     RewriteRule ^/Artocarpus/([^/]+)$ /var/www/cgi-bin/Artocarpus/$1.cgi [L,QSA]
512
513     # 规则3:根目录简洁URL → 执行根目录CGI
514     RewriteCond %{REQUEST_URI} !\.htm$
515     RewriteCond %{REQUEST_URI} !\.html$
516     RewriteCond %{REQUEST_URI} !\.css$
517     RewriteCond %{REQUEST_URI} !\.js$
518     RewriteCond %{REQUEST_URI} !\.png$
519     RewriteCond %{REQUEST_URI} !\.jpg$
520     RewriteCond %{REQUEST_URI} !\.gif$
521     RewriteCond %{REQUEST_URI} !\.ico$
522     RewriteCond %{REQUEST_URI} !^/Artocarpus/
523     RewriteCond %{REQUEST_URI} !^/cgi-bin/
524     RewriteCond %{REQUEST_FILENAME} !-f
525     RewriteCond %{REQUEST_FILENAME} !-d
526     RewriteCond %{REQUEST_URI} ^/[^/]+$
527     RewriteRule ^/([^/]+)$ /var/www/cgi-bin/$1.cgi [L,QSA]
528
529     <Directory "/var/www/html/Artocarpus">
530         Options Indexes FollowSymLinks
531         Require all granted
532     </Directory>
533
534     <Directory "/var/www/cgi-bin/Artocarpus">
535         Options +ExecCGI
536         SetHandler cgi-script
537         Require all granted
538     </Directory>
539
540     <Directory "/var/www/cgi-bin">
541         Options +ExecCGI
542         SetHandler cgi-script
543         Require all granted
544     </Directory>
545
546     ErrorLog /var/log/httpd/morac_error.log
547     CustomLog /var/log/httpd/morac_access.log combined
548 </VirtualHost>

~

#######################################################

######################################################

#deepseek修改一个小bug(url访问必须带/)后版本,未测试

<VirtualHost *:80>
    ServerName morac.ficusgd.com
    DocumentRoot /var/www/html

    ScriptAlias /cgi-bin/ /var/www/cgi-bin/

    RewriteEngine On

    # ========== 新增:目录斜杠自动重定向 ==========
    # 规则0:自动为目录添加斜杠(必须在其他规则之前)
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteCond %{REQUEST_URI} !/$
    RewriteRule ^(.*)$ $1/ [R=301,L]

    # ========== 原有的重定向规则 ==========
    # 规则1a:重定向 /cgi-bin/Artocarpus/*.cgi
    RewriteRule ^/cgi-bin/Artocarpus/(.+)\.cgi$ /Artocarpus/$1 [R=307,L,QSA]

    # 规则1b:重定向 /Artocarpus/*.cgi
    RewriteRule ^/Artocarpus/(.+)\.cgi$ /Artocarpus/$1 [R=307,L,QSA]

    # 规则1c:重定向 /cgi-bin/*.cgi → /*
    RewriteRule ^/cgi-bin/([^/]+)\.cgi$ /$1 [R=307,L,QSA]

    # 规则1d:重定向 /*.cgi → /*
    RewriteCond %{REQUEST_URI} !^/Artocarpus/
    RewriteCond %{REQUEST_URI} !^/cgi-bin/
    RewriteRule ^/([^/]+)\.cgi$ /$1 [R=307,L,QSA]

    # ========== 修改后的内部重写规则 ==========
    # 规则2:内部重写 - 处理 Artocarpus 下的CGI请求
    # 排除对目录本身的处理
    RewriteCond %{REQUEST_URI} !^/Artocarpus/?$  # 排除 /Artocarpus 目录本身
    RewriteCond %{REQUEST_URI} !\.(htm|html|css|js|png|jpg|gif|ico)$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^/Artocarpus/([^/]+)/?$ /var/www/cgi-bin/Artocarpus/$1.cgi [L,QSA]

    # 规则3:根目录简洁URL → 执行根目录CGI
    RewriteCond %{REQUEST_URI} !\.(htm|html|css|js|png|jpg|gif|ico)$
    RewriteCond %{REQUEST_URI} !^/Artocarpus
    RewriteCond %{REQUEST_URI} !^/cgi-bin/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^/([^/]+)/?$ /var/www/cgi-bin/$1.cgi [L,QSA]

    # ========== 原有的目录配置 ==========
    <Directory "/var/www/html/Artocarpus">
        Options Indexes FollowSymLinks
        # 确保设置了默认索引文件
        DirectoryIndex index.html index.php
        Require all granted
    </Directory>

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

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

    ErrorLog /var/log/httpd/morac_error.log
    CustomLog /var/log/httpd/morac_access.log combined
</VirtualHost>