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" : [
                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                ]
            },
            /* 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": "/"
  • 配置文件完成了,那么代码里面的该怎么去写呢

<view class="detail_title"  @click="pulldown(index)">
        <img src="static/bill_icon_water@2x.png" class="detail_type"/>
                    {{items.ln_policy_title}}
        <img src="static/bill_icon_pulldown_pressed@2x.png" class="detail_jian" :class="{xuan:index == indexa&&detail == true}" />
</view>
  • 不要问我static 目录放在放在那里,连接看向这里 uni-app 开发规范
  • 最终访问资源的路径为: https://h5.example.com/static/bill_icon_pulldown_pressed@2x.png, 这个路径是根据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. 如果有不对的地方,大佬尽情指教,联系方式:
        me@raybon.vip

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

说个问题, 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 时候的一个兼容问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容