uni-app 多站点部署针对static 等静态资源访问以及跨域解决方案

冷静一下心情:


30v33r30j1g.jpg
问题: 最近有一批项目是uni-app 开发的,外包团队给的源码部署后出现了图片资源无法访问等现象
            

解决方案:这个涉及到前台和服务器之间的配置, 除了配置,代码上也需要调整,下面给出单站点和多站点访问的设置

1. 单站点访问

  • 我们先了解一下 uni-app 的配置文件[manifest.json]
{
    "name" : "******",
    "appid" : "****",
    "description" : "",
    "versionName" : "1.0.0",
    "versionCode" : "100",
    "transformPx" : false,
    "debug" : false,
    /* 5+App特有相关 */
    "app-plus" : {
        "usingComponents" : true,
        "nvueCompiler" : "uni-app",
        "splashscreen" : {
            "alwaysShowBeforeRender" : true,
            "waiting" : true,
            "autoclose" : true,
            "delay" : 0
        },
        /* 模块配置 */
        "modules" : {},
        /* 应用发布信息 */
        "distribute" : {
            /* android打包配置 */
            "android" : {
                "permissions" : [
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    ""
                ]
            },
            /* ios打包配置 */
            "ios" : {},
            /* SDK配置 */
            "sdkConfigs" : {}
        }
    },
    /* 快应用特有相关 */
    "quickapp" : {},
    /* 小程序特有相关 */
    "mp-weixin" : {
        "appid" : "",
        "setting" : {
            "urlCheck" : false
        },
        "usingComponents" : true
    },
    "mp-alipay" : {
        "usingComponents" : true
    },
    "mp-baidu" : {
        "usingComponents" : true
    },
    "mp-toutiao" : {
        "usingComponents" : true
    },
    "h5" : {
        "title" : "--------",
        "router" : {
            "mode" : "hash",
            "base" : "/" // 注意此处的base 并不是给访问的路由增加前缀的 和下面的publicPath 要区分开
        },
        "publicPath" : "/"   // 此处的单站点直接设置为 `/` 就行
    }
}

  • 我们把H5 这一部分抽离出来进行配置
"h5" : {
        "title" : "--------",
        "router" : {
            "mode" : "hash",
            "base" : "/" 
        },
        "publicPath" : "/"  // 注意是 yarn build:h5 才会使用这个路径
    }
  • uni-app 配置文件我们看过了,看下什么是单站点访问

    • 比如: 我们设置的域名为: https://h5.example.com 访问的路径是我们打包后的 dist/build/h5/index.html, 这种情况我们 配置文件设置成 "base : "/", 同时 "publicPath": "/"
  • 配置文件完成了,那么代码里面的该怎么去写呢


        
                    {{items.ln_policy_title}}
        

  • 不要问我static 目录放在放在那里,连接看向这里 uni-app 开发规范
  • 最终访问资源的路径为: https://h5.example.com/static/[email protected], 这个路径是根据domain 地址加上 配置文件的 base 生成的,能解决掉资源丢失的问题
  • 可能有人会问 为什么不用 @/static/image.png 这种形式,经过查阅文档发现,这种方案是可行的,也是我自己推荐的,但是我们如果图片过大,这种在执行 npm build:h5 指令后,有些大图并不能转成 base64 还是无法解析 ,所以方案你们可以根据场景去使用
  • 【新增加的】 由于uni-app 不建议我们重写vue.config.js 那么 大图模式下 我们采用 src="/static/img/logo.png" ,此时需要检查项目 src 目录下manifest.json 文件里面的H5 的 router base 配置和 publicPath 配置保持统一,这样方便测试和正式环境都能正确识别路径 【重要重要重要
  • 单站点不涉及服务器内容,所以后台提供什么,你们就按照什么格式进行打包就行

2. nginx 多站点 h5 访问时部署


  • 多站点是什么意思

    • 简单来说就是一台nginx 上面配置了多个二级地址供外面访问,比如 之前我们 访问 https://h5.example.com , 现在可能需要访问 https://h5.example.com/payhttps://h5.example.com/noticehttps://h5.example.com/work 等等这些带有sub-path 的访问
    • 这个时候我们先把配置弄好
    "h5" : {
        "title" : "物业公告",
        "router" : {
            "mode" : "hash",
            "base" : "/notice/"  此处填写当前sub-path 对应的路径  此处可改成 pay or notice or word
        },
        "publicPath" : "./"  此处注意一点, 需要设置成 `./` 此处用于生成index.html 引用JS文件位置
    }
    
    • Vue 页面内针对 static 目录下的文件访问, 参考单站点的写法
    • 前端修改的地方不是很多,下面看服务器对多站点的解析
    server {
    listen 80;
    server_name h5.example.com;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/h5.example.com/;
    
    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    #SSL-END
    
    #ERROR-PAGE-START  错误页配置,可以注释、删除或修改
    #error_page 404 /404.html;
    #error_page 502 /502.html;
    #ERROR-PAGE-END
    
    #PHP-INFO-START  PHP引用配置,可以注释或修改
    include enable-php-73.conf;
    #PHP-INFO-END
    
    #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
    include /www/server/panel/vhost/rewrite/h5.example.com.conf;
    #REWRITE-END
    
    #禁止访问的文件或目录
    location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
    {
        return 404;
    }
    
    #一键申请SSL证书验证目录相关设置
    location ~ \.well-known{
        allow all;
    }
    
    location /graphql-file {
        proxy_pass https://www.example.com/graphql-file;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    }
    
   # 代理访问
    location /graphql {
        proxy_pass https://www.example.com/graphql;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    
    location ^~ /pay {
        index index.html index.htm;
        autoindex on;
        alias /www/wwwroot/h5.example.comfrontend/pay/dist/build/h5;
    }
    
    location ^~ /notice {
        index index.html index.htm;
        autoindex on;
        alias /www/wwwroot/h5.example.com/notice/dist/build/h5;
    }

    
    location ^~ /work {
        index index.html index.htm;
        autoindex on;
        alias /www/wwwroot/h5.example.com/work/dist/build/h5;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
        expires      30d;
        error_log off;
        access_log /dev/null;
    }
    
    location ~ .*\.(js|css)?$
    {
        expires      12h;
        error_log off;
        access_log /dev/null; 
    }

    location / {
        try_files $uri $uri/ /index.html;
      }
    
    access_log  /www/wwwlogs/access.log;
    error_log  /www/wwwlogs/error.log;

}
  • 服务器配置完毕,我们需要针对 nginx 执行 nginx -t 来检测 ,检测通过 执行 nginx -s reload

  • 多站点的配置到这里我们就完成了

3. 前后端分离的针对跨域的设置

  • 比如前端访问 https://h5.example.com , 里面API 调用的是 https://api.h5.example.com ,访问时前端会出现一个 options 的请求, 此时,我们最简单的办法就是在nginx 里面设置个uri 拦截
location ^~ /api {
        proxy_pass https://api.h5.example.com/api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    }
  • 注意H5内部的改动,前端此时的request 请求的baseUrl 还是访问 http://example.com

4. 总结:

  • 针对以上两种方案,我们都是在生产环境直接上用的, 开发环境这样配置也是没什么影响的哦

  • 本地如何设置成多环境的呢

      1. 本地新建一个 json 文件 env.example.json
      1. Mac 环境 执行 cp env.example.json env.json , Wins 环境 copy env.example.json env.json 或者 手动拷贝一份,名字改成 env.json
      1. 将env.json 文件添加到 .gitignore 文件中 并在代码中使用的地方进行引用
      1. 文件内容为:
    {
      "env" : "production",
      "base_url": "http://h5.example.com",
      "city": "shanghai",
      "map_url": "https://api.map.baidu.com/geocoder/v2/?ak=ak",
      "callback_url": "'call_url'"
    }
    
      1. 注意一点 uni-app 内 等价webpack 的文件是 vue.config.js 具体是否能用需要看uni-app 文档哦
      1. 如果有不对的地方,大佬尽情指教,联系方式:
        [email protected]

标注 新增加的,是自己测试中发现的一个加载问题

说个问题, uni-app 内部如果加载的静态资源图片大于 8192 字节 时,采用 / 方式加载, 如果是 小于这个数值 采用 @ 符号进行处理,
具体可查看 先关文档 【webpack url-loader】url-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ]
  }
}

以上是在处理 uni-app 时候的一个兼容问题

你可能感兴趣的:(uni-app 多站点部署针对static 等静态资源访问以及跨域解决方案)