美文网首页
[server-notes] vuecli3.0 history

[server-notes] vuecli3.0 history

作者: liwuwuzhi | 来源:发表于2020-12-30 17:00 被阅读0次

    实现同个域名下部署多个项目,通过不同url来区分调用对应项目:
    如:
    http://xxxx:8090/app1 展示项目1
    http://xxxx:8090/app2 展示项目2


    相关文档请查阅:HTML5 History 模式


    1. 修改router基础路径:

    base,应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 "/app/"

    引自:Vue Router base

    根据: http://xxxx:8090/app1
    我的项目需要部署到/app1/下,所以配置为 base:‘app1’

    2. 修改静态文件输入路径:

    publicPath,部署应用包时的基本 URL。
    默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上,例如 https://www.my-app.com/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.my-app.com/my-app/,则设置 publicPath 为 /my-app/。

    引自:Vue Cli publicPath

    根据: http://xxxx:8090/app1
    vue.config.js文件:
    publicPath: 'app1' ,值为应用的基路径
    publicPath: '' ,或者值为空字符串

    注意点:

    • 从 Vue CLI 3.3 起 baseUrl 已弃用,改为用publicPath
    • publicPath: './' publicPath 可以设置成相对路径,但是并不推荐。
      这样所有的资源都会被链接为相对路径,在HTML5 history.pushState(即history模式)的路由时或使用 pages 选项构建多页面应用时会有限制。

    3. nginx配置:

    上传到nginx并配置nginx不同项目的路径:

    3.1:我的nginx的文件根目录html文件夹如下:

    3.2:我的server配置:

    try_files 也可以用 rewrite方法来实现:

    location /app1/ {
      if (!-e $request_filename) {
         rewrite ^/(.*) /app1/index.html last;
         break;
      }
    }
    

    如果$request_filename (/html/app1/sub_page)不存在, 则会直接重定向至index.html ,在index.html 中让vue的router自己去处理。

    3.3 修改配置后,一定一定重启服务,配置才会生效。

    nginx -s reload
    




    相关的几个问题:

    # 为什么刷新会404?#

    在配置vue 路由的nginx时,首先要确认你的vue路由采用的是hash 模式还是hestory模式,

    如果是history模式,

    location /app1/{
        root html;
        index index.html index.html;
    }
    

    项目按照正常的逻辑去点击,不会出现问题,但是一旦刷新,就会出现404,

    1.nginx 目录 /html/app1/ 下面有发布的vue静态资源,有index.html 和一些js css。

    2.访问 http://xxxx:8090/app1/index.html

    3.nginx 匹配会在/html下面去找app1/index.html 这个是可以找到的。

    4.但是当点击其他的页面,vue路由跳转到了/subpage;链接变成了 http://sss.sss.com/app1/subpage

    这时nginx还会在/html 下面去找app1/subpage,很可惜,没找到。

    这是因为vue的路由不是真实的路由,而nginx是按照真实的文件目录路径去请求的,这时,nginx 肯定找不到vue的非index的路由,404。

    # try_files 配置与重定向#

    [ try_files ]
    语法:
        格式1:try_files file ... uri;
        格式2:try_files file ... =code;
    默认值:-
    配置段:server、location

    try_file路径匹配。Nginx会按顺序检查文件及目录是否存在(根据 root 和 alias 指令设置的参数构造完整的文件路径),并用找到的第一个文件提供服务。在元素名后面添加斜杠 / 表示这个是目录。如果文件和目录都不存在,Nginx会执行内部重定向跳转到命令的最后一个 uri 参数定义的 URI 中。

    可以分为几个点来理解:

    • 按指定的file顺序查找存在的文件,并返回第一个找到的文件或文件夹;
    • 查找路径是按照给定的root或alias为根路径来查找的;
    • 如果给出的file都没有匹配到,则重新请求最后一个参数给定的uri,就是新的location匹配;
    • 只有最后一个参数可以引起一个内部重定向,是请求,之前的参数只设置内部URI的指向;
    • 最后一个参数是回退URI且必须存在,否则会出现内部500错误;
    • 格式2,如果最后一个参数是 = 404 ,若给出的file都没有匹配到,则最后返回404的响应码。
    格式1示例:
    server {
        listen 80;
        server_name linux.web.com;
    
        location / {
            root /code;
            try_files $uri $uri/ /index.html;
        }
    }
    

    当请求 linux.web.com/2.html 时,会依次匹配

    1. /code/2.html文件
    2. /code/2.html/文件夹下的 index.html 文件,即查找 /code/2.html/index.html(结尾加斜线表示为文件夹)
    3. 请求linux.web.com/code/index.html 。重定向到应用的初始页面 index.html,那么路径的匹配就交回给了前端,让前端router自己去匹配并跳转。

    这也是为什么vue + nginx 在非主业刷新404问题的原因。

    格式2示例:
    server {
        listen 80;
        server_name linux.web.com;
    
        location / {
            root /code;
            try_files $uri =404;
        }
    }
    

    当访问linux.web.com/2.html(文件存在)时,返回/code/2.html内容
    当访问linux.web.com/2.html(文件不存在)时,返回404状态
    也可以使用一个文件作为最后一个参数,如果最后一个参数是文件,那么这个文件必须存在。

    # nginx配置root、alias 的区别#

    nginx指定文件路径有两种方式root和alias。主要区别在于如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。

    区别:

    • 映射路径的方式不同;
    • alias 只能作用在location中,而root可以存在server、http、location中;
    • alias 后面必须要用 “/” 结束,否则会找不到文件,而 root 则对 ”/” 可有可无。

    [ root ]
    语法:root path
    默认值:root html
    配置段:http、server、location、if in location
    例如:

    location /img/ {
        root /data/w3;
    }
    

    root会根据完整的URI请求来映射。即资源真实的路径是root指定的值加上location指定的值。
    当请求 http://xxx.com/img/top.gif 时,那么在服务器里面对应的真正的资源是: /data/w3/img/top.gif

    [ alias ]
    语法:alias path
    默认值:-
    配置段:location
    例如:

    location /img/ {
        alias /data/w3/images/;
    }
    

    alias,别名,指代的是location。即不管location的值怎么写,资源的真实路径都是 alias 指定的路径。
    当请求 http://xxx.com/img/top.gif 时,在服务器查找的资源路径是: /data/w3/images/top.gif

    # 案例#


    有项目 用户端(smuser) 和 管理系统端(sm_admin);

    期望访问形式为:
    用户端:http://xxx.com/smuser
    管理系统端:http://xxx.com/sm_admin

    项目位置为:
    用户端: /usr/local/project/sm_client;
    管理系统端:/usr/local/project/sm_admin;

    nginx.conf 设置如下:

    server {
        listen 80;
        server_name linux.web.com;
    
       location / {
          root  html;
          index index.html index.htm;
        }
    
       location /smuser {
          alias /usr/local/project/sm/sm_client/;
          index index.html;
          try_files $uri $uri/ /smuser/index.html; # or try_files $uri $uri/ /smuser=404;
       }
    
       location /sm_admin {
          root /usr/local/project/sm;
          try_files $uri $uri/ /sm_admin/index.html;
       }
    }
    

    vue项目配置,以 sm_admin 项目为例:
    主要修改的又:(1) 修改router基础路径:base: 'sm_admin'(2) 修改静态文件输入路径:publicPath: ''
    因为项目打包,接口域名可能不一样,所以在开发和生产上做了不同的配置,如下:

    1)在根目录下新键以 .env开头的文件: .env.dev 和 .env.prod:

    用法:

    • .env.dev 和 .env.prod 文件需在项目根目录下;
    • 自定义属性以 VUE_APP 开头,属性值默认为字符串形式,不用自己再加引号。例如
      设置:VUE_APP_TITLE:zhou
      获取:console.log(process.env.VUE_APP_TITLE) // "zhou"
    • 在 package.json 文件设置以 env.dev / .env.prod 启动/打包 文件
    • 修改配置之后需要重启才生效
     "scripts": {
        "serve": "vue-cli-service serve --mode dev",
        "build": "vue-cli-service build --mode prod",
        "lint": "vue-cli-service lint"
      },
    

    2)修改静态文件输入路径
    vue.config.js:

    
    module.exports = {
      publicPath: '',
      devServer: {
        proxy: {
          '/api': {
            target: process.env.VUE_APP_BASE_API, // API服务器的地址
            ws: true, // 代理websockets
            changeOrigin: true, // 虚拟的站点需要更管origin
            pathRewrite: { // 重写路径 比如'/api/aaa/ccc'重写为'/aaa/ccc'
              '^/api': '/api'
            }
          }
        },
        disableHostCheck: true,
      }
    }
    

    3)修改router基础路径
    router:

    const router = new VueRouter({
      mode: 'history',
      base: process.env.VUE_APP_BASE_ROUTER,
      routes
    })
    

    4)设置api域名
    api:

    const http = axios.create({
      baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '',
      timeout: 120000
    })
    

    如果在开发环境配置了代理 devServer.proxy,那么此时 baseURL需设置为空或默认不设置。


    相关:
    使用nginx部署多个前端项目-网页url太长怎么换
    nginx配置vue项目,带项目名

    相关文章

      网友评论

          本文标题:[server-notes] vuecli3.0 history

          本文链接:https://www.haomeiwen.com/subject/mxnfoktx.html