Files
lucky_shop/docs/HISTORY_MODE_SUB_DIR_DEPLOY.md

21 KiB
Raw Permalink Blame History

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

场景说明

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

配置步骤

1. 应用配置(已完成)

确保manifest.json中的H5路由配置正确设置了base路径:

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

2. 服务器配置

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

2.1 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/目录下)
<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>
虚拟主机配置
<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 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配置

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/

"h5": {
  "router": {
    "mode": "history",
    "base": "/hwapp/"
  }
}

应用2部署到 /hwappx/test/

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

应用3部署到 /hwappx/comoon/

"h5": {
  "router": {
    "mode": "history",
    "base": "/hwappx/comoon/"
  }
}

应用4部署到 /hwappx/1000/

"h5": {
  "router": {
    "mode": "history",
    "base": "/hwappx/1000/"
  }
}

2. 服务器多子目录配置

2.1 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

<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

<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

<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

<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在主配置文件中统一配置
<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 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 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 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 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配置

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来匹配子目录模式

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文件中添加:

<IfModule mod_rewrite.c>
  RewriteEngine On
  
  # 匹配 /hwapp/ 一级子目录
  RewriteRule ^hwapp/(.*)$ /hwapp/index.html [L]
  
  # 匹配 /hwappx/ 下的所有二级子目录
  RewriteRule ^hwappx/([^/]+)/(.*)$ /hwappx/$1/index.html [L]
</IfModule>
方法2在虚拟主机配置中使用
<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 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配置

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验证是否能正常加载

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