Vue代理报错404问题及解决(vue配置proxy)

lxf2023-05-08 22:05:01
摘要

这篇文章主要介绍了Vue代理报错404问题及解决(vue配置proxy),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

目录
  • Vue代理报错404问题
    • 第一种路径拼接 /api 情况
    • 第二种路径不变情况
    • 注意点
    • 新增说明:配置多个代理怎么搞?
  • 总结

    Vue代理报错404问题

    问题描述:

    Vue代理报错404问题及解决(vue配置proxy)

    代理后出现404:

    Vue代理报错404问题及解决(vue配置proxy)

    第一种路径拼接 /api 情况

    const path = require('path');
    
    function resolve(dir) {
        return path.resolve(__dirname, dir)
    }
    module.exports = {
        publicPath: process.env.node_ENV === "production" ? "./" : "/",
        assetsDir: "assets",
        configurewebpack: {
            resolve: {
                extensions: ['.js', '.vue', '.JSON'],
                alias: {
                    '@': resolve('src'),
                    'assets': resolve('src/assets'),
                    'CSS': resolve('src/assets/css'),
                    'images': resolve('src/assets/images'),
                    'views': resolve('src/views'),
                    'components': resolve('src/components'),
                    'api': resolve('src/api'),
                    'mixins': resolve('src/mixins'),
                    'store': resolve('src/store'),
                    'service': resolve('src/service'),
                }
            }
        },
        devServer: {
            port: 8081,
            hot: true,
            // open: 'Chrome',
            proxy: {
                // change xxx-api/login => mock/login
                // detail: https://cli.vuejs.org/config/#devserver-proxy
                '/api': {
                    target: 'Https://www.xxxxxx.com/', 
                    changeOrigin: true,
                    secure: true,
                    pathRewrite: {
                        '^/api': '/'
                    }
                },
            },
        },
        css: {
            loaderOptions: {
                css: {},
                postcss: {
                    plugins: [
                        require('postcss-px2rem')({
                            remUnit: 192
                        })
                    ]
                }
            }
        },
        productionSourceMap: false,
    };
    
    

    Vue代理报错404问题及解决(vue配置proxy)

    使用如下:

    Vue代理报错404问题及解决(vue配置proxy)

    结果如下:

    Vue代理报错404问题及解决(vue配置proxy)

    缺点 :打包后的请求路径会多个 /api

    第二种路径不变情况

    Vue代理报错404问题及解决(vue配置proxy)

    这种写法也可以:

    Vue代理报错404问题及解决(vue配置proxy)

    注意:这时候就按原来的路径就可以了;

    Vue代理报错404问题及解决(vue配置proxy)

    结果如下:

    Vue代理报错404问题及解决(vue配置proxy)

    缺点:配置多个代理要注意代理的先后顺序;

    注意点

    代理的顺序:从前往后匹配的,先匹配到哪个就用哪个;

    新增说明:配置多个代理怎么搞?

    配置多个代理怎么搞?

    'use strict'
    const path = require('path')
    // const SkeletonWEBpackPlugin = require('vue-skeleton-webpack-plugin')
    const defaultSettings = require('./src/settings.js')
    
    function resolve(dir) {
      return path.join(__dirname, dir)
    }
    
    const name = defaultSettings.title || 'xxx' // page title
    
    // If your port is set to 80,
    // use administrator privileges to execute the command line.
    // For example, Mac: sudo npm run
    // You can change the port by the following methods:
    // port = 9527 npm run dev OR npm run dev --port = 9527
    const port = process.env.port || process.env.npm_config_port || 9527 // dev port
    
    // All configuration item explanations can be find in https://cli.vuejs.org/config/
    module.exports = {
      
      // publicPath: process.env.ENV === 'production' ? '/' : '/',
      publicPath: process.env.ENV === 'production' ? '/' : '/',
      outputDir: 'dist',
      assetsDir: 'static',
      lintOnSave: process.env.NODE_ENV === 'development',
      productionSourceMap: false,
      devServer: {
        host: 'localhost',//target host
        port: port,
        overlay: {
          warnings: false,
          errors: true
        },
        proxy: {
          [process.env.VUE_APP_BASE_BRAND_API]: {
            target: 'http://10.44.62.64:8090',
            changeOrigin: true,
            pathRewrite: {
              ['^' + process.env.VUE_APP_BASE_BRAND_API]: ''
            }
          },
          // change xxx-api/login => mock/login
          // detail: https://cli.vuejs.org/config/#devserver-proxy
          [process.env.VUE_APP_BASE_API]: {
            // target: 'http://localhost:3100',
            target: 'http://xx.xxx.xx.x:3100',
            // target: `http://127.0.0.1:${port}/mock`,
            changeOrigin: true,
            pathRewrite: {
              ['^' + process.env.VUE_APP_BASE_API]: ''
            }
          },
        },
        // proxy:{
        //   // 当你请求是以/api开头的时候,则我帮你代理访问到http://localhost:3000
        //   // 例如:
        //   // /api/users  http://localhost:3000/api/users
        //   // 我们真是服务器接口是没有/api的
        //   "":{
        //     target:"http://localhost:31009",
        //     changeOrigin: true,// 如果接口跨域,需要进行这个参数配置
        //     pathRewrite:{"^":""}
        //   }
        // }
        // after: require('./mock/mock-server.js')
      },
      configureWebpack: {
        // provide the app's title in webpack's name field, so that
        // it can be accessed in index.html to inject the correct title.
        name: name,
        resolve: {
          alias: {
            '@': resolve('src')
          }
        }
      },
      // css: {
      //   extract: true // 是否使用css分离插件 ExtractTextPlugin(开启骨架屏必须这个配置)
      // },
      chainWebpack(config) {
        config.plugin('html').tap(args => {
          // 添加初始化变量
          args[0].monitorId = process.env.VUE_APP_MONITOR_ID
          return args
        })
    
        config.plugins.delete('preload') // TODO: need test
        config.plugins.delete('prefetch') // TODO: need test
    
        // set svg-sprite-loader
        config.module
          .rule('svg')
          .exclude.add(resolve('src/icons'))
          .end()
        config.module
          .rule('icons')
          .test(/\.svg$/)
          .include.add(resolve('src/icons'))
          .end()
          .use('svg-sprite-loader')
          .loader('svg-sprite-loader')
          .options({
            symbolId: 'icon-[name]'
          })
          .end()
    
        // set preserveWhitespace
        config.module
          .rule('vue')
          .use('vue-loader')
          .loader('vue-loader')
          .tap(options => {
            options.compilerOptions.preserveWhitespace = true
            return options
          })
          .end()
    
        config
          // https://webpack.js.org/configuration/devtool/#development
          .when(process.env.NODE_ENV === 'development',
            config => config.devtool('cheap-source-map')
          )
    
        config
          .when(process.env.NODE_ENV !== 'development',
            config => {
              config
                .plugin('ScriptExtHtmlWebpackPlugin')
                .after('html')
                .use('script-ext-html-webpack-plugin', [{
                  // `runtime` must same as runtimeChunk name. default is `runtime`
                  inline: /runtime\..*\.js$/
                }])
                .end()
              config
                .optimization.splitChunks({
                  chunks: 'all',
                  cacheGroups: {
                    libs: {
                      name: 'chunk-libs',
                      test: /[\\/]node_modules[\\/]/,
                      priority: 10,
                      chunks: 'initial' // only package third parties that are initially dependent
                    },
                    elementUI: {
                      name: 'chunk-elementUI', // split elementUI into a single package
                      priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                      test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                    },
                    commons: {
                      name: 'chunk-commons',
                      test: resolve('src/components'), // can customize your rules
                      minChunks: 3, //  minimum common number
                      priority: 5,
                      reuseExistinGChunk: true
                    }
                  }
                })
              config.optimization.runtimeChunk('single')
            }
          )
    
        // 骨架屏配置
        // config
        //   .plugin('SkeletonWebpackPlugin')
        //   .use(new SkeletonWebpackPlugin({
        //     webpackConfig: {
        //       entry: {
        //         app: resolve('src/skeleton.js'),
        //       }
        //     },
        //     minimize: true,
        //     quiet: true,
        //     router: {
        //       mode: 'history',
        //       routes: [{
        //         path: '*',
        //         skeletonId: 'common-skeleton'
        //       }]
        //     }
        //   }))
      }
    }
    

    注意.env.development中的配置

    NODE_ENV = 'development'
    
    # just a flag
    ENV = 'development'
    
    # base api(当使用mock.js时,切换dev-api)
    # VUE_APP_BASE_API = '/dev-api'
    VUE_APP_BASE_API = ''
    
    # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
    # to control whether the babel-plugin-dynamic-import-node plugin is enabled.
    # It only does one thing by converting all import() to require().
    # This configuration can significantly increase the speed of hot updates,
    # when you have a large number of pages.
    # Detail:  https://GitHub.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
    
    VUE_CLI_BABEL_TRANSPILE_MODULES = true
    
    # 图片和附件上传文件夹
    VUE_APP_OSS_FOLDER='test/xxx/'
    
    # 品牌项目 (这里为了代理,要多加个 /brand,当然可以自己定义)
    VUE_APP_BASE_BRAND_API = '/brand'
    
    

    配置了 .env.development 中的代理路径后,这样api接口js文件中就不用多写个 /brand,不用写成 /brand/saveOrUpdate ,请求路径也会存在 /brand ,baseURL拼接的原因,这样打包也并不影响,毕竟打包的是生产环境的路径;

    Vue代理报错404问题及解决(vue配置proxy)

    Vue代理报错404问题及解决(vue配置proxy)

    Vue代理报错404问题及解决(vue配置proxy)

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。