# H5 History模式子目录部署配置指南

## 场景说明
您的uni-app H5应用部署在现有网站的子目录 `/hwappx/test/` 下，需要使用`history`路由模式，并解决刷新页面空白的问题。

## 配置步骤

### 1. 应用配置（已完成）
确保`manifest.json`中的H5路由配置正确设置了`base`路径：

```json
"h5": {
    "router": {
        "mode": "history",
        "base": "/hwappx/test/"
    }
}
```

### 2. 服务器配置
服务器需要配置路由回退，将所有指向`/hwappx/test/`下不存在文件的请求重定向到`/hwappx/test/index.html`。

#### 2.1 Nginx配置
```nginx
server {
    listen 80;
    server_name yourdomain.com;
    
    # 主网站根目录
    root /path/to/main/website;
    index index.html;
    
    # 静态文件直接返回
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|ttf|woff|woff2)$ {
        expires 7d;
        add_header Cache-Control "public, no-transform";
    }
    
    # H5应用子目录的路由回退配置
    location /hwappx/test/ {
        # 确保静态文件能被正确访问
        try_files $uri $uri/ /hwappx/test/index.html;
    }
    
    # 主网站的其他配置
    location / {
        # 主网站的原有配置
    }
}
```

#### 2.2 Apache配置

##### .htaccess文件配置（放在`/hwappx/test/`目录下）
```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /hwappx/test/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /hwappx/test/index.html [L]
</IfModule>
```

##### 虚拟主机配置
```apache
<VirtualHost *:80>
    ServerName yourdomain.com
    DocumentRoot /path/to/main/website
    
    # H5应用子目录配置
    <Directory /path/to/main/website/hwappx/test>
        AllowOverride All
        Require all granted
        
        RewriteEngine On
        RewriteBase /hwappx/test/
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /hwappx/test/index.html [L]
    </Directory>
    
    # 主网站目录配置
    <Directory /path/to/main/website>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
```

#### 2.3 IIS配置
在`/hwappx/test/`目录下创建`web.config`文件：

```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="History Mode Sub Directory">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/hwappx/test/index.html" />
        </rule>
      </rules>
    </rewrite>
    <staticContent>
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
    </staticContent>
  </system.webServer>
</configuration>
```

#### 2.4 Express.js配置
```javascript
const express = require('express');
const path = require('path');
const app = express();

// 主网站静态文件
app.use(express.static(path.join(__dirname, 'main-website')));

// H5应用静态文件和路由回退
app.use('/hwappx/test', express.static(path.join(__dirname, 'h5-app')));

app.get('/hwappx/test/*', (req, res) => {
    res.sendFile(path.join(__dirname, 'h5-app', 'index.html'));
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});
```

## 配置关键点

1. **base路径一致性**：
   - `manifest.json`中的`base`配置必须与部署路径一致：`/hwappx/test/`
   - 服务器配置中的重定向路径必须包含完整的base路径

2. **静态资源处理**：
   - 确保CSS、JS、图片等静态资源能够被正确访问
   - 静态资源的URL应该自动包含base路径

3. **路由回退规则**：
   - 规则必须限定在`/hwappx/test/`路径下
   - 只重定向不存在的文件和目录请求

## 验证方法

1. 构建H5应用并部署到服务器的`/hwappx/test/`目录
2. 访问应用首页：`http://yourdomain.com/hwappx/test/`
3. 导航到子页面：`http://yourdomain.com/hwappx/test/pages_tool/form/formdata?id=73&uniacid=2793`
4. 刷新页面，验证页面是否正常显示

## 常见问题排查

1. **404错误**：
   - 检查服务器配置中的重定向路径是否正确
   - 确保`base`路径配置一致

2. **页面样式缺失**：
   - 检查静态资源URL是否包含了正确的base路径
   - 确认CSS文件路径是否正确

3. **路由无法跳转**：
   - 检查`manifest.json`中的路由配置
   - 确认服务器重定向规则是否生效

## 部署注意事项

1. 配置完成后需要重启服务器
2. 对于HTTPS站点，需要在对应的HTTPS配置中添加相同的规则
3. 如果使用CDN，需要确保CDN也配置了相应的路由回退规则
4. 定期检查服务器日志，确保配置正常工作

## 总结
通过正确配置应用的`base`路径和服务器的路由回退规则，您的uni-app H5应用可以在子目录`/hwappx/test/`下成功使用`history`路由模式，并且解决刷新页面空白的问题。

---

## 多子目录部署支持

### 场景说明
如果您需要在同一服务器上部署多个使用`history`模式的uni-app H5应用，例如：
- `/hwapp/`
- `/hwappx/test/`
- `/hwappx/comoon/`
- `/hwappx/1000/`

您可以按照以下配置方法实现多子目录部署。

### 1. 每个应用的manifest.json配置
每个应用都需要在`manifest.json`中配置正确的`base`路径：

#### 应用1：部署到 `/hwapp/`
```json
"h5": {
  "router": {
    "mode": "history",
    "base": "/hwapp/"
  }
}
```

#### 应用2：部署到 `/hwappx/test/`
```json
"h5": {
  "router": {
    "mode": "history",
    "base": "/hwappx/test/"
  }
}
```

#### 应用3：部署到 `/hwappx/comoon/`
```json
"h5": {
  "router": {
    "mode": "history",
    "base": "/hwappx/comoon/"
  }
}
```

#### 应用4：部署到 `/hwappx/1000/`
```json
"h5": {
  "router": {
    "mode": "history",
    "base": "/hwappx/1000/"
  }
}
```

### 2. 服务器多子目录配置

#### 2.1 Nginx配置
```nginx
server {
    listen 80;
    server_name yourdomain.com;
    root /path/to/main/website;
    index index.html;

    # 静态文件缓存设置
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|ttf|woff|woff2)$ {
        expires 7d;
        add_header Cache-Control "public, no-transform";
    }

    # 应用1: /hwapp/
    location /hwapp/ {
        try_files $uri $uri/ /hwapp/index.html;
    }

    # 应用2: /hwappx/test/
    location /hwappx/test/ {
        try_files $uri $uri/ /hwappx/test/index.html;
    }

    # 应用3: /hwappx/comoon/
    location /hwappx/comoon/ {
        try_files $uri $uri/ /hwappx/comoon/index.html;
    }

    # 应用4: /hwappx/1000/
    location /hwappx/1000/ {
        try_files $uri $uri/ /hwappx/1000/index.html;
    }

    # 主网站其他配置
    location / {
        # 原有主网站配置
    }
}
```

#### 2.2 Apache配置

##### 方法1：在每个子目录下创建.htaccess文件

在`/hwapp/`目录下创建.htaccess：
```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /hwapp/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /hwapp/index.html [L]
</IfModule>
```

在`/hwappx/test/`目录下创建.htaccess：
```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /hwappx/test/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /hwappx/test/index.html [L]
</IfModule>
```

在`/hwappx/comoon/`目录下创建.htaccess：
```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /hwappx/comoon/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /hwappx/comoon/index.html [L]
</IfModule>
```

在`/hwappx/1000/`目录下创建.htaccess：
```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /hwappx/1000/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /hwappx/1000/index.html [L]
</IfModule>
```

##### 方法2：在主配置文件中统一配置
```apache
<VirtualHost *:80>
    ServerName yourdomain.com
    DocumentRoot /path/to/main/website

    # 应用1: /hwapp/
    <Directory /path/to/main/website/hwapp>
        AllowOverride All
        Require all granted
        
        RewriteEngine On
        RewriteBase /hwapp/
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /hwapp/index.html [L]
    </Directory>

    # 应用2: /hwappx/test/
    <Directory /path/to/main/website/hwappx/test>
        AllowOverride All
        Require all granted
        
        RewriteEngine On
        RewriteBase /hwappx/test/
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /hwappx/test/index.html [L]
    </Directory>

    # 应用3: /hwappx/comoon/
    <Directory /path/to/main/website/hwappx/comoon>
        AllowOverride All
        Require all granted
        
        RewriteEngine On
        RewriteBase /hwappx/comoon/
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /hwappx/comoon/index.html [L]
    </Directory>

    # 应用4: /hwappx/1000/
    <Directory /path/to/main/website/hwappx/1000>
        AllowOverride All
        Require all granted
        
        RewriteEngine On
        RewriteBase /hwappx/1000/
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /hwappx/1000/index.html [L]
    </Directory>

    # 主网站目录配置
    <Directory /path/to/main/website>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
```

#### 2.3 IIS配置

在每个子目录下创建`web.config`文件：

##### 应用1：/hwapp/web.config
```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="History Mode hwapp">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/hwapp/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

##### 应用2：/hwappx/test/web.config
```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="History Mode hwappx/test">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/hwappx/test/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

##### 应用3：/hwappx/comoon/web.config
```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="History Mode hwappx/comoon">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/hwappx/comoon/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

##### 应用4：/hwappx/1000/web.config
```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="History Mode hwappx/1000">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/hwappx/1000/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

#### 2.4 Express.js配置
```javascript
const express = require('express');
const path = require('path');
const app = express();

// 主网站静态文件
app.use(express.static(path.join(__dirname, 'main-website')));

// 应用1: /hwapp/
app.use('/hwapp', express.static(path.join(__dirname, 'h5-app1')));
app.get('/hwapp/*', (req, res) => {
    res.sendFile(path.join(__dirname, 'h5-app1', 'index.html'));
});

// 应用2: /hwappx/test/
app.use('/hwappx/test', express.static(path.join(__dirname, 'h5-app2')));
app.get('/hwappx/test/*', (req, res) => {
    res.sendFile(path.join(__dirname, 'h5-app2', 'index.html'));
});

// 应用3: /hwappx/comoon/
app.use('/hwappx/comoon', express.static(path.join(__dirname, 'h5-app3')));
app.get('/hwappx/comoon/*', (req, res) => {
    res.sendFile(path.join(__dirname, 'h5-app3', 'index.html'));
});

// 应用4: /hwappx/1000/
app.use('/hwappx/1000', express.static(path.join(__dirname, 'h5-app4')));
app.get('/hwappx/1000/*', (req, res) => {
    res.sendFile(path.join(__dirname, 'h5-app4', 'index.html'));
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});
```

### 3. 多子目录部署验证

对于每个应用，执行以下验证步骤：

1. 构建应用并部署到对应的子目录
2. 访问应用首页，例如：`http://yourdomain.com/hwappx/test/`
3. 导航到子页面，例如：`http://yourdomain.com/hwappx/test/pages_tool/form/formdata?id=73&uniacid=2793`
4. 刷新页面，验证页面是否正常显示
5. 直接访问子页面URL，验证是否能正常加载

### 4. 多子目录部署注意事项

1. **路径隔离**：每个应用必须部署在独立的子目录下，避免文件和路由冲突
2. **base一致性**：每个应用的`manifest.json`中的`base`配置必须与部署路径完全一致
3. **服务器规则**：每个子目录都需要独立的路由回退规则
4. **静态资源**：确保每个应用的静态资源URL包含了正确的base路径
5. **缓存设置**：可以为不同应用设置不同的缓存策略
6. **日志分离**：建议为不同应用配置独立的访问日志，便于问题排查

### 5. 常见问题排查

1. **应用间冲突**：
   - 确保每个应用使用独立的子目录
   - 检查`base`路径配置是否唯一

2. **路由混乱**：
   - 验证服务器配置中的重定向路径是否正确
   - 检查应用的路由配置是否与其他应用冲突

3. **静态资源404**：
   - 确认静态资源URL是否包含了正确的base路径
   - 检查服务器配置是否正确处理了静态资源请求

4. **配置不生效**：
   - 配置完成后重启服务器
   - 清除浏览器缓存后重试

通过以上配置，您可以在同一服务器上成功部署多个使用`history`模式的uni-app H5应用，每个应用都能独立运行并支持刷新操作。

---

## 通配符配置方案

### 场景说明
如果您的子目录有明确的命名规则（如您的`/hwapp/`、`/hwappx/test/`、`/hwappx/comoon/`、`/hwappx/1000/`等），可以使用通配符配置来简化服务器设置，避免为每个子目录手动添加配置。

### 子目录规则分析
根据您的子目录结构，可以分为两类：
1. 一级子目录：`/hwapp/`
2. `/hwappx/`下的所有二级子目录：`/hwappx/*/`

### 服务器通配符配置

#### 1. Nginx配置
使用正则表达式location来匹配子目录模式：

```nginx
server {
    listen 80;
    server_name yourdomain.com;
    root /path/to/main/website;
    index index.html;

    # 静态文件缓存设置
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|ttf|woff|woff2)$ {
        expires 7d;
        add_header Cache-Control "public, no-transform";
    }

    # 匹配 /hwapp/ 一级子目录
    location = /hwapp/ {
        try_files $uri $uri/ /hwapp/index.html;
    }

    location ~ ^/hwapp/(.*)$ {
        try_files $uri $uri/ /hwapp/index.html;
    }

    # 匹配 /hwappx/ 下的所有二级子目录，如 /hwappx/test/、/hwappx/comoon/、/hwappx/1000/ 等
    location ~ ^/hwappx/([^/]+)/(.*)$ {
        # 提取子目录名，重定向到对应目录的index.html
        try_files $uri $uri/ /hwappx/$1/index.html;
    }

    # 主网站其他配置
    location / {
        # 原有主网站配置
    }
}
```

#### 2. Apache配置

##### 方法1：使用RewriteRule的正则表达式

在主网站根目录的`.htaccess`文件中添加：

```apache
<IfModule mod_rewrite.c>
  RewriteEngine On
  
  # 匹配 /hwapp/ 一级子目录
  RewriteRule ^hwapp/(.*)$ /hwapp/index.html [L]
  
  # 匹配 /hwappx/ 下的所有二级子目录
  RewriteRule ^hwappx/([^/]+)/(.*)$ /hwappx/$1/index.html [L]
</IfModule>
```

##### 方法2：在虚拟主机配置中使用

```apache
<VirtualHost *:80>
    ServerName yourdomain.com
    DocumentRoot /path/to/main/website

    RewriteEngine On
    
    # 匹配 /hwapp/ 一级子目录
    RewriteRule ^/hwapp/(.*)$ /hwapp/index.html [L]
    
    # 匹配 /hwappx/ 下的所有二级子目录
    RewriteRule ^/hwappx/([^/]+)/(.*)$ /hwappx/$1/index.html [L]

    # 主网站目录配置
    <Directory /path/to/main/website>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
```

#### 3. IIS配置

在主网站根目录的`web.config`文件中添加：

```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <!-- 匹配 /hwapp/ 一级子目录 -->
        <rule name="History Mode hwapp Wildcard" stopProcessing="true">
          <match url="^hwapp/.*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/hwapp/index.html" />
        </rule>
        
        <!-- 匹配 /hwappx/ 下的所有二级子目录 -->
        <rule name="History Mode hwappx Wildcard" stopProcessing="true">
          <match url="^hwappx/([^/]+)/.*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/hwappx/{R:1}/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

#### 4. Express.js配置

```javascript
const express = require('express');
const path = require('path');
const app = express();

// 主网站静态文件
app.use(express.static(path.join(__dirname, 'main-website')));

// 匹配 /hwapp/ 一级子目录
app.use('/hwapp', express.static(path.join(__dirname, 'hwapp')));
app.get('/hwapp/*', (req, res) => {
    res.sendFile(path.join(__dirname, 'hwapp', 'index.html'));
});

// 匹配 /hwappx/ 下的所有二级子目录
// 使用路由参数来捕获子目录名
app.get('/hwappx/:subdir/*', (req, res) => {
    const subdir = req.params.subdir;
    const appPath = path.join(__dirname, `hwappx/${subdir}`);
    
    // 检查应用目录是否存在
    const fs = require('fs');
    if (fs.existsSync(appPath)) {
        res.sendFile(path.join(appPath, 'index.html'));
    } else {
        res.status(404).send('Application not found');
    }
});

// 为 /hwappx/ 下的每个子目录提供静态文件服务
app.use('/hwappx', express.static(path.join(__dirname, 'hwappx')));

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});
```

### 通配符配置优势

1. **减少配置量**：无需为每个新子目录手动添加配置
2. **自动适应**：新添加的符合规则的子目录会自动应用路由回退
3. **统一管理**：所有同类应用的配置集中管理，便于维护
4. **规则灵活**：可以根据实际需要调整正则表达式匹配规则

### 通配符配置注意事项

1. **规则顺序**：确保更具体的规则优先于通配符规则
2. **性能考虑**：过于复杂的正则表达式可能影响服务器性能
3. **目录验证**：在Express.js等代码级配置中，建议添加目录存在性检查
4. **冲突避免**：确保通配符规则不会与主网站或其他应用的路由冲突
5. **测试充分**：配置后要充分测试各种子目录的访问情况

### 验证方法

1. 部署一个符合规则的新子目录应用，如 `/hwappx/newapp/`
2. 访问应用首页：`http://yourdomain.com/hwappx/newapp/`
3. 导航到子页面并刷新，验证是否正常显示
4. 直接访问子页面URL，验证是否能正常加载

通过以上通配符配置，您可以轻松管理大量符合规则的子目录应用，避免重复配置工作。