vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
67.48k stars 6.08k forks source link

Vite proxying with https doesn't work #6102

Closed rachitpant closed 1 year ago

rachitpant commented 2 years ago

Describe the bug

We have an existing project with a vue ( vue-cli ) front end that we are trying to migrate to vite, and a backend that only accepts secure https requests. We are using a wildcard certificate for *.companydomain.org and most developers have updated their etc/hots local redirect URL with local.companydomain.org. We do this because the backend only accepts strictly https requests.

Everything was working fine in the vue-cli project. However as we are attempting to migrate it to vite , the one and only thing we aren't able to get done is proxying to the backend server ( no API requests are proxied ).

Here is the old vue.config.js file.

// These values are used to configure the vue devServer.  They can be overriden using a .env file.
HOST = process.env.ENV_HOST || '0.0.0.0' // IP or hostname the vue dev server should be bound to (0.0.0.0 uses 'localhost" and your external ip)
PORT = process.env.ENV_PORT || '8080' // port for the vue proxy server
HTTPS = process.env.ENV_HTTPS == 'true' ? true : false // enable or disable https for the vue proxy server
PFX = process.env.ENV_PFX || '' // PKCS12 ksystore for ssl certificate
PFX_PASSPHRASE = process.env.ENV_PFX_PASSPHRASE || '' // passphrase for ssl keystore
SERVER_URL = process.env.ENV_SERVER_URL || 'http://localhost:8447' // host where the spring boot server is running / target of the proxy server

// vue.config.js
module.exports = {
  // proxy all webpack dev-server requests starting with /api
  // to our Spring Boot backend (localhost:8088) using http-proxy-middleware
  // see https://cli.vuejs.org/config/#devserver-proxy
  devServer: {
    host: HOST,
    port: PORT,
    https: HTTPS,
    pfx: PFX,
    pfxPassphrase: PFX_PASSPHRASE,
    proxy: {
      '/': {
        target: SERVER_URL, // this configuration needs to correspond to the Spring Boot backends' application.properties server.port
        ws: true,
        changeOrigin: true
      }
    }
  },
  // Change build paths to make them Maven compatible
  // see https://cli.vuejs.org/config/
  outputDir: 'target/classes/public',
  assetsDir: 'static',
  publicPath: '/eventdirect/',
  configureWebpack: {
    devtool: 'source-map'
    // ,
    // externals: {
    //   dropzone: 'dropzone'
    // }
  }
}

As you can see we are proxying all "/" requests to the backend , and the vue.cli dev server was smart enough to only proxy the API requests. The javascript chunk requests were never proxied. This didn't work with vite dev server , so I attempted to add a baseUrlto axios in main.js

if (import.meta.env.DEV) {
  axios.defaults.baseURL = 'api'
} 

And here is the corresponding vite.config.js // These values are used to configure the vue devServer. They can be overriden using a .env file.

import { defineConfig, loadEnv } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import path from 'path'

export default ({ mode }) => {
  process.env = { ...process.env, ...loadEnv(mode, process.cwd(), 'VUE_') }

  HOST = process.env.VUE_ENV_HOST || '0.0.0.0' // IP or hostname the vue dev server should be bound to (0.0.0.0 uses 'localhost" and your external ip)
  PORT = process.env.VUE_ENV_PORT || '8080' // port for the vue proxy server
  HTTPS = process.env.VUE_ENV_HTTPS == 'true' ? true : false // enable or disable https for the vue proxy server
  PFX = process.env.VUE_ENV_PFX || '' // PKCS12 ksystore for ssl certificate
  PFX_PASSPHRASE = process.env.VUE_ENV_PFX_PASSPHRASE || '' // passphrase for ssl keystore
  SERVER_URL = process.env.VUE_ENV_SERVER_URL || 'http://localhost:8447' // host where the spring boot server is running / target of the proxy server
  console.log(SERVER_URL)
  console.log(HOST)
  return defineConfig({
    envPrefix: 'VUE_',
    base: '/eventdirect/',
    plugins: [createVuePlugin()],
    server: {
      host: HOST,
      port: PORT,
      https: {
        pfx: PFX,
        passphrase: PFX_PASSPHRASE
      }
    },
    resolve: {
      alias: [
        {
          find: '@',
          replacement: path.resolve(__dirname, 'src')
        }
      ]
    },
    proxy: {
      '^/api/.*': {
        target: SERVER_URL,
        changeOrigin: true,
        secure: false,
        rewrite: path => path.replace(/^\/api/, ''),
        ssl: {
          pfx: PFX,
          passphrase: PFX_PASSPHRASE
        }
      }
    },
    build: {
      chunkSizeWarningLimit: 600,
      cssCodeSplit: false
    }
  })
}

We are trying to make as little change as possible , the only change in the above vite config file ( compared to vue config) is that , the environment variables are changed , they start with a prepend of VUE_ , and 2 , the proxying doesn't work.

There are multiple bugs reported earlier , and I am pretty sure this is a bug, that just hasn't been addressed yet.

Reproduction

Please see the vite config above , can't upload our certificates to reproduce it. As mentioned earlier , the same backend worked for vue-cli , and vue cli config is also uploaded.

System Info

System:
    OS: macOS 10.15.7
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
    Memory: 193.15 MB / 16.00 GB
    Shell: 3.2.57 - /bin/sh
  Binaries:
    Node: 14.16.1 - ~/.nvm/versions/node/v14.16.1/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.14.12 - ~/.nvm/versions/node/v14.16.1/bin/npm
  Browsers:
    Chrome: 96.0.4664.93
    Firefox: 95.0
    Safari: 13.1.3
  npmPackages:
    vite: ^2.7.1 => 2.7.1

Used Package Manager

yarn

Logs

vite:spa-fallback Rewriting GET / to /index.html +15s
  vite:time 2.13ms /index.html +15s
  vite:cache [304] /@vite/client +16s
  vite:time 1.14ms /@vite/client +62ms
  vite:cache [304] /src/main.js +1ms
  vite:time 0.48ms /src/main.js +1ms
  vite:cache [304] /src/App.vue +82ms
  vite:time 0.48ms /src/App.vue +82ms
  vite:cache [304] /src/router.js +1ms
  vite:time 0.48ms /src/router.js +1ms
  vite:cache [304] /node_modules/vue-datetime/dist/vue-datetime.css +1ms
  vite:time 0.54ms /node_modules/vue-datetime/dist/vue-datetime.css +1ms
  vite:cache [304] /src/assets/css/ncaaApps.css +1ms
  vite:time 0.56ms /src/assets/css/ncaaApps.css +1ms
  vite:cache [304] /src/store/index.js +1ms
  vite:time 0.65ms /src/store/index.js +2ms
  vite:cache [304] /src/validation.js +17ms
  vite:time 0.52ms /src/validation.js +16ms
  vite:cache [304] /node_modules/vuejs-dialog/dist/vuejs-dialog.min.css +64ms
  vite:time 0.55ms /node_modules/vuejs-dialog/dist/vuejs-dialog.min.css +64ms
  vite:cache [304] /node_modules/vite/dist/client/env.mjs +24ms
  vite:time 0.55ms /node_modules/vite/dist/client/env.mjs +24ms
  vite:cache [304] /src/App.vue?vue&type=template&lang.js +211ms
  vite:time 0.62ms /src/App.vue?vue&type=template&lang.js +211ms
  vite:cache [304] /src/App.vue?vue&type=style&index=0&lang.scss +1ms
  vite:time 0.62ms /src/App.vue?vue&type=style&index=0&lang.scss +1ms
  vite:cache [304] /vite/vueComponentNormalizer +1ms
  vite:time 0.32ms /@id/__x00__/vite/vueComponentNormalizer +1ms
  vite:cache [304] /vite/vueHotReload +1ms
  vite:time 0.29ms /@id/__x00__/vite/vueHotReload +1ms
  vite:cache [304] /src/components/MyEvent.vue +4ms
  vite:time 0.89ms /src/components/MyEvent.vue +4ms
  vite:cache [304] /src/components/Messages.vue +2ms
  vite:time 0.61ms /src/components/Messages.vue +2ms
  vite:cache [304] /src/components/Forms.vue +2ms
  vite:time 0.92ms /src/components/Forms.vue +2ms
  vite:cache [304] /src/components/Users.vue +2ms
  vite:time 1.95ms /src/components/Users.vue +2ms
  vite:cache [304] /src/components/Files.vue +2ms
  vite:time 0.65ms /src/components/Files.vue +2ms
  vite:cache [304] /src/components/SessionExpired.vue +1ms
  vite:time 0.56ms /src/components/SessionExpired.vue +1ms
  vite:cache [304] /src/components/Error.vue +1ms
  vite:time 0.69ms /src/components/Error.vue +1ms
  vite:cache [304] /src/components/EditEvent.vue +1ms
  vite:time 0.61ms /src/components/EditEvent.vue +1ms
  vite:cache [304] /src/components/GlobalRoles.vue +1ms
  vite:time 0.51ms /src/components/GlobalRoles.vue +1ms
  vite:cache [304] /src/store/modules/inbox/index.js +2ms
  vite:time 1.08ms /src/store/modules/inbox/index.js +2ms
  vite:cache [304] /src/store/modules/sent-items/index.js +1ms
  vite:time 0.72ms /src/store/modules/sent-items/index.js +1ms
  vite:cache [304] /src/store/modules/trash/index.js +12ms
  vite:time 0.64ms /src/store/modules/trash/index.js +12ms
  vite:cache [304] /src/store/modules/drafts/index.js +35ms
  vite:time 1.33ms /src/store/modules/drafts/index.js +35ms
  vite:cache [304] /src/store/modules/userList/index.js +1ms
  vite:time 0.77ms /src/store/modules/userList/index.js +1ms
  vite:cache [304] /src/store/modules/groupList/index.js +1ms
  vite:time 0.61ms /src/store/modules/groupList/index.js +2ms
  vite:cache [304] /src/store/modules/message.js +1ms
  vite:time 0.53ms /src/store/modules/message.js +1ms
  vite:cache [304] /src/store/modules/scheduled.js +1ms
  vite:time 0.57ms /src/store/modules/scheduled.js +1ms
  vite:cache [304] /src/store/modules/files.js +2ms
  vite:time 0.69ms /src/store/modules/files.js +1ms
  vite:cache [304] /src/store/modules/forms.js +1ms
  vite:time 0.56ms /src/store/modules/forms.js +1ms
  vite:cache [304] /src/store/modules/currentUser.js +1ms
  vite:time 0.64ms /src/store/modules/currentUser.js +1ms
  vite:cache [304] /src/store/modules/calendarEvents.js +1ms
  vite:time 0.73ms /src/store/modules/calendarEvents.js +1ms
  vite:cache [304] /src/store/modules/eventData/index.js +2ms
  vite:time 0.75ms /src/store/modules/eventData/index.js +2ms
  vite:cache [304] /src/components/MyEvent.vue?vue&type=template&lang.js +429ms
  vite:time 0.87ms /src/components/MyEvent.vue?vue&type=template&lang.js +429ms
  vite:cache [304] /src/components/Users.vue?vue&type=template&lang.js +1ms
  vite:time 0.69ms /src/components/Users.vue?vue&type=template&lang.js +1ms
  vite:cache [304] /src/components/SessionExpired.vue?vue&type=template&lang.js +1ms
  vite:time 0.62ms /src/components/SessionExpired.vue?vue&type=template&lang.js +1ms
  vite:cache [304] /src/components/SessionExpired.vue?vue&type=style&index=0&lang.css +1ms
  vite:time 0.68ms /src/components/SessionExpired.vue?vue&type=style&index=0&lang.css +1ms
  vite:cache [304] /src/components/newMessage.vue +1ms
  vite:time 0.57ms /src/components/newMessage.vue +1ms
  vite:cache [304] /src/components/Messages.vue?vue&type=template&lang.js +1ms
  vite:time 0.61ms /src/components/Messages.vue?vue&type=template&lang.js +1ms
  vite:cache [304] /src/components/Forms.vue?vue&type=template&lang.js +1ms
  vite:time 0.76ms /src/components/Forms.vue?vue&type=template&lang.js +2ms
  vite:cache [304] /node_modules/dropzone/dist/dropzone.css +2ms
  vite:time 0.55ms /node_modules/dropzone/dist/dropzone.css +1ms
  vite:cache [304] /src/assets/img/fileicons/folder.png +2ms
  vite:time 1.14ms /src/assets/img/fileicons/folder.png?import +2ms
  vite:cache [304] /src/assets/img/fileicons/text.png +1ms
  vite:time 0.60ms /src/assets/img/fileicons/text.png?import +1ms
  vite:cache [304] /src/assets/img/fileicons/pdf.png +2ms
  vite:time 1.18ms /src/assets/img/fileicons/pdf.png?import +2ms
  vite:cache [304] /src/assets/img/fileicons/movie.png +2ms
  vite:time 1.41ms /src/assets/img/fileicons/movie.png?import +2ms
  vite:cache [304] /src/assets/img/fileicons/binary.png +2ms
  vite:time 2.42ms /src/assets/img/fileicons/binary.png?import +3ms
  vite:cache [304] /src/assets/img/fileicons/image.png +1ms
  vite:time 0.48ms /src/assets/img/fileicons/image.png?import +0ms
  vite:cache [304] /src/assets/img/fileicons/html.png +1ms
  vite:time 0.43ms /src/assets/img/fileicons/html.png?import +1ms
  vite:cache [304] /src/assets/img/fileicons/blank.png +1ms
  vite:time 1.23ms /src/assets/img/fileicons/blank.png?import +2ms
  vite:cache [304] /src/components/Files.vue?vue&type=template&lang.js +2ms
  vite:time 0.93ms /src/components/Files.vue?vue&type=template&lang.js +1ms
  vite:cache [304] /src/components/Files.vue?vue&type=style&index=0&lang.css +1ms
  vite:time 1.29ms /src/components/Files.vue?vue&type=style&index=0&lang.css +2ms
  vite:cache [304] /src/store/modules/inbox/state.js +2ms
  vite:time 0.67ms /src/store/modules/inbox/state.js +1ms
  vite:cache [304] /src/store/modules/inbox/getters.js +1ms
  vite:time 0.60ms /src/store/modules/inbox/getters.js +2ms
  vite:cache [304] /src/store/modules/inbox/mutations.js +1ms
  vite:time 0.55ms /src/store/modules/inbox/mutations.js +0ms
  vite:cache [304] /src/store/modules/inbox/actions.js +1ms
  vite:time 0.52ms /src/store/modules/inbox/actions.js +1ms
  vite:cache [304] /src/components/Error.vue?vue&type=template&lang.js +1ms
  vite:time 0.78ms /src/components/Error.vue?vue&type=template&lang.js +1ms
  vite:cache [304] /src/components/Error.vue?vue&type=style&index=0&lang.css +1ms
  vite:time 0.64ms /src/components/Error.vue?vue&type=style&index=0&lang.css +1ms
  vite:cache [304] /src/components/EditEvent.vue?vue&type=template&lang.js +1ms
  vite:time 0.56ms /src/components/EditEvent.vue?vue&type=template&lang.js +1ms
  vite:cache [304] /src/store/modules/sent-items/state.js +1ms
  vite:time 0.50ms /src/store/modules/sent-items/state.js +1ms
  vite:cache [304] /src/store/modules/sent-items/getters.js +1ms
  vite:time 0.75ms /src/store/modules/sent-items/getters.js +1ms
  vite:cache [304] /src/store/modules/sent-items/mutations.js +1ms
  vite:time 0.62ms /src/store/modules/sent-items/mutations.js +1ms
  vite:cache [304] /src/store/modules/sent-items/actions.js +1ms
  vite:time 0.55ms /src/store/modules/sent-items/actions.js +1ms
  vite:cache [304] /src/components/GlobalRoles.vue?vue&type=template&lang.js +1ms
  vite:time 0.64ms /src/components/GlobalRoles.vue?vue&type=template&lang.js +1ms
  vite:cache [304] /src/components/GlobalRoles.vue?vue&type=style&index=0&lang.css +1ms
  vite:time 0.66ms /src/components/GlobalRoles.vue?vue&type=style&index=0&lang.css +1ms
  vite:cache [304] /src/store/modules/trash/state.js +2ms
  vite:time 1.63ms /src/store/modules/trash/state.js +2ms
  vite:cache [304] /src/store/modules/trash/getters.js +1ms
  vite:time 0.81ms /src/store/modules/trash/getters.js +1ms
  vite:cache [304] /src/store/modules/trash/mutations.js +1ms
  vite:time 0.67ms /src/store/modules/trash/mutations.js +1ms
  vite:cache [304] /src/store/modules/trash/actions.js +1ms
  vite:time 0.52ms /src/store/modules/trash/actions.js +1ms
  vite:cache [304] /src/store/modules/drafts/state.js +1ms
  vite:time 0.65ms /src/store/modules/drafts/state.js +1ms
  vite:cache [304] /src/store/modules/drafts/getters.js +1ms
  vite:time 0.58ms /src/store/modules/drafts/getters.js +1ms
  vite:cache [304] /src/store/modules/drafts/mutations.js +1ms
  vite:time 0.63ms /src/store/modules/drafts/mutations.js +1ms
  vite:cache [304] /src/store/modules/drafts/actions.js +1ms
  vite:time 0.59ms /src/store/modules/drafts/actions.js +1ms
  vite:cache [304] /src/store/modules/userList/state.js +1ms
  vite:time 0.51ms /src/store/modules/userList/state.js +1ms
  vite:cache [304] /src/store/modules/userList/getters.js +1ms
  vite:time 0.52ms /src/store/modules/userList/getters.js +1ms
  vite:cache [304] /src/store/modules/userList/mutations.js +1ms
  vite:time 0.56ms /src/store/modules/userList/mutations.js +1ms
  vite:cache [304] /src/store/modules/userList/actions.js +1ms
  vite:time 0.79ms /src/store/modules/userList/actions.js +1ms
  vite:cache [304] /src/store/modules/groupList/state.js +1ms
  vite:time 0.96ms /src/store/modules/groupList/state.js +1ms
  vite:cache [304] /src/store/modules/groupList/getters.js +5ms
  vite:time 0.76ms /src/store/modules/groupList/getters.js +6ms
  vite:cache [304] /src/store/modules/groupList/mutations.js +2ms
  vite:time 0.67ms /src/store/modules/groupList/mutations.js +1ms
  vite:cache [304] /src/store/modules/groupList/actions.js +1ms
  vite:time 0.60ms /src/store/modules/groupList/actions.js +1ms
  vite:cache [304] /src/store/modules/eventData/state.js +1ms
  vite:time 0.79ms /src/store/modules/eventData/state.js +1ms
  vite:cache [304] /src/store/modules/eventData/getters.js +1ms
  vite:time 0.70ms /src/store/modules/eventData/getters.js +1ms
  vite:cache [304] /src/store/modules/eventData/mutations.js +1ms
  vite:time 0.69ms /src/store/modules/eventData/mutations.js +1ms
  vite:cache [304] /src/store/modules/eventData/actions.js +2ms
  vite:time 0.57ms /src/store/modules/eventData/actions.js +2ms
  vite:cache [304] /src/components/UserSelect.vue +417ms
  vite:time 0.80ms /src/components/UserSelect.vue +417ms
  vite:cache [304] /src/components/newMessage.vue?vue&type=template&lang.js +2ms
  vite:time 0.82ms /src/components/newMessage.vue?vue&type=template&lang.js +2ms
  vite:cache [304] /src/assets/img/something broke.png +1ms
  vite:time 0.58ms /src/assets/img/something%20broke.png?import +1ms
  vite:cache [304] /node_modules/vue-select/dist/vue-select.css +84ms
  vite:time 0.57ms /node_modules/vue-select/dist/vue-select.css +84ms
  vite:cache [304] /src/components/UserSelect.vue?vue&type=template&lang.js +2ms
  vite:time 0.63ms /src/components/UserSelect.vue?vue&type=template&lang.js +3ms
  vite:time 1.00ms /node_modules/.vite/chunk-GHKCA547.js.map +253ms
  vite:time 1.03ms /node_modules/.vite/luxon.js.map +78ms
  vite:time 0.85ms /node_modules/.vite/@fortawesome_fontawesome-svg-core.js.map +237ms
  vite:spa-fallback Not rewriting GET /api/public/getEvents because the client prefers JSON. +2s
  vite:time 2.49ms /api/public/getEvents +53ms
  vite:spa-fallback Not rewriting GET /api/getUserInfo because the client prefers JSON. +3ms
  vite:time 2.73ms /api/getUserInfo +3ms
  vite:time 0.59ms /src/assets/img/trophies2.jpg +192ms

Validations

rachitpant commented 2 years ago

Here is a screenshot of 404 being returned for API requests. image

jsjoeio commented 2 years ago

@rachitpant did you ever find a workaround?

rachitpant commented 2 years ago

Nope.

On Fri, Dec 24, 2021 at 12:05 AM Joe Previte @.***> wrote:

@rachitpant https://github.com/rachitpant did you ever find a workaround?

— Reply to this email directly, view it on GitHub https://github.com/vitejs/vite/issues/6102#issuecomment-1000656439, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALH6363VGEXIWQ7ZTCYK63USP5P5ANCNFSM5J7AESVQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

rachitpant commented 2 years ago

Vite experts any comments ?? At first I thought if there is something wrong in my proxy rewrite config.

 proxy: {
      '^/api/.*': {
        target: SERVER_URL,
        changeOrigin: true,
        secure: false,
        rewrite: path => path.replace(/^\/api/, ''),
        ssl: {
          pfx: PFX,
          passphrase: PFX_PASSPHRASE
        }
      }
    },

But as we can see if the logs above , the vite server is not even attempting to rewrite which is why the requests are not proxied. vite:spa-fallback Not rewriting GET /api/getUserInfo because the client prefers JSON. +3ms

import-brain commented 2 years ago

@patak-dev Please label as bug

patak-dev commented 2 years ago

@import-brain thanks for the heads up! If you tested and confirmed that it is a bug, you can say so without tagging a particular maintainer, everyone that is watching the repo will get the notification and the closest one will label it :)

import-brain commented 2 years ago

@import-brain thanks for the heads up! If you tested and confirmed that it is a bug, you can say so without tagging a particular maintainer, everyone that is watching the repo will get the notification and the closest one will label it :)

Ah, I didn't realize you guys had your notifications set up like that, thanks for the heads up!

I get the error on my end, so it should be the same for you guys.

rachitpant commented 2 years ago

My bad .. this is not a bug , I had to account for the baseUrl in addition white configuring proxy. Here is the working config. Also this should have been inside the server tag , but i am not sure why i put it outside. Corrected that as well and its working fine.

proxy: {
        '^/eventdirect/api/.*': {
          target: SERVER_URL,
          changeOrigin: true,
          rewrite: path => path.replace('/api', ''),
          ssl: {
            pfx: PFX,
            passphrase: PFX_PASSPHRASE
          }
        }
      }

My only suggestion would be that in the doesProxyContextMatchUrl function , we should probably check if request url starts with the base (already passed in the config ) , exclude that from testing the regex or string starts with.

Either that , or if we can't do that , we can improve the server proxy config documentation to tell that the base url has to be explicitly prepended.. ( if there is any ).

import-brain commented 2 years ago

My bad .. this is not a bug , I had to account for the baseUrl in addition white configuring proxy. Here is the working config. Also this should have been inside the server tag , but i am not sure why i put it outside. Corrected that as well and its working fine.

proxy: {
        '^/eventdirect/api/.*': {
          target: SERVER_URL,
          changeOrigin: true,
          rewrite: path => path.replace('/api', ''),
          ssl: {
            pfx: PFX,
            passphrase: PFX_PASSPHRASE
          }
        }
      }

My only suggestion would be that in the doesProxyContextMatchUrl function , we should probably check if request url starts with the base (already passed in the config ) , exclude that from testing the regex or string starts with.

Either that , or if we can't do that , we can improve the server proxy config documentation to tell that the base url has to be explicitly prepended.. ( if there is any ).

Wow, I can't believe I missed that too, we should probably include this in the docs.

xuanxiaocheng commented 2 years ago

If want to use all "/" requests to let it only proxy the API requests,we can use vite plugin api “configureServer”. Combined with http-proxy-middleware to implement proxy filtering.

const { createProxyMiddleware } = require('http-proxy-middleware')
export default function serverProxy() {
  return {
    name: 'serverProxy',
    configureServer(server) {
      const filter = function (pathname, req) {
        return typeof req.headers['x-ajax'] != 'undefined'
      }
      server.middlewares.use(
        '/',
        createProxyMiddleware(filter, {
          target: 'http://localhost:3000',
          changeOrigin: true
        })
      )
    }
  }
}
AbdelHadi commented 2 years ago

Hello Everyone ! I have the same issue with server proxy The requests returns 404 when user navigate in a nested route app.url/ => works fine app.url/test/tests => doesn't work Could you please help?