vbenjs / vite-plugin-html

A vite plugin for processing html. It is developed based on lodash template
MIT License
597 stars 96 forks source link

Version 3 breaks vite proxy #38

Open xrado opened 2 years ago

xrado commented 2 years ago

In version v2.7.13 all worked fine, after upgrading to v3 (3.0.6) vite server proxy settings do work anymore if accessed directly via browser. Lets say I have in my vite config:

server: {
    proxy: {
        '/api': 'http://localhost:3000'
    },
}

calling localhost:8000/api/list directly from my browser always serves index.html only async XHR calls after initial load goes through the proxy.

anncwb commented 2 years ago

can you give me a reproduction?

xrado commented 2 years ago

@anncwb here https://stackblitz.com/edit/vitejs-vite-j1uvi4?file=vite.config.js&terminal=dev

open and add /api to the end of preview url, enter and click the preview reload button empty page, does not load because tries to load http://localhost:3000 via proxy

uncomment createHtmlPlugin, save and try again /api always loads index.html because vite proxy is ignored or overriden somehow

oscartbeaumont commented 2 years ago

I am having this same issue but it was a bit confusing to work out because the proxying only fails when the client accepts text/html, so some of my API requests were getting through.

This is being caused by the configureServer Vite plugin API (used here) which is catching all HTTP requests if the client accepts text/html hence preventing Vite from proxying them.

I am not sure why you are using the configureServer API in the first place because transformIndexHtml is run by Vite when the devserver is enabled which should achieve the functionality you need. I think it's worth looking at removing it or at least making it an optional (disabled by default) feature as this custom devserver will probably introduce more issues down the road as Vite make internal changes even if you were to make a workaround for this specific issue.

oscartbeaumont commented 2 years ago

I am also happy to PR the change if requested.

anncwb commented 2 years ago

PR welcome

oscartbeaumont commented 2 years ago

It looks like this change was fixed in release 3.2.0. @anncwb or @xrado can we get this issue closed.

xrado commented 2 years ago

still doesn't solve the issue for me. Vite proxy settings are still overridden by the plugin on the initial load of the page. Lets say I want to open api endpoint url in the new tab to see the response, instead of the response index.html loads.

Renderz commented 2 years ago

It looks like this change was fixed in release 3.2.0. @anncwb or @xrado can we get this issue closed.

still not working.

ex0ns commented 2 years ago

I also have issue with the vite proxy whenever vite-plugin-html is used in the configuration (see https://github.com/vitejs/vite/issues/7999). As explained on this issue this is only happening when the header Accept: html or Accept: application/xhtml+xml is present

https://stackblitz.com/edit/vitejs-vite-2chcqw?file=index.html

yarn vite serve --debug

In index.html you can try to comment/uncomment the Accept header line In vite.config.js if you remove/comment the html plugin, this works fine as well

I guess this issue might be out of the scope of vite ? I don't know enough about plugins to understand how they could have such an influence on the server and proxy

After looking at the last commit on this repo, and because of the reproduction, I'm pretty sure that this is related to https://github.com/vbenjs/vite-plugin-html/commit/e0813a7911c3f882a58106de95531016b5f5e245#diff-9d3607e4c1e85762d487319c0c4714c9d72ef03164358e8d2d428368cc86adbeR90

erm1116 commented 2 years ago

I also have same issue. And trying to remove below lines, it works fine. https://github.com/vbenjs/vite-plugin-html/blob/841d4ef04c3cf5ff0d4339350ae336aa83aa70ed/packages/core/src/htmlPlugin.ts#L87-L93

I don't clearly understand why these lines are needed. (maybe, history mode support for vue-router ?) Can't we remove this?

vellengs commented 2 years ago

同样遇到这个问题,导致接口的查询参数丢失。

JackieCheung commented 2 years ago

same problem, any progress now?

kilobyte2007 commented 2 years ago

Hey, we have the same problem. It seems the plugin drops all of the query parameters that are passed when accessed via a browser (so with the accepts headers). I am not sure entirely why the middleware with the htmlAcceptHeaders is needed so it's hard to think of a fix but if someone can explain it I'd be happy to make a PR.

moroz1k commented 1 year ago

same problem

ehossack commented 1 year ago

Also have this problem, and tested locally that this fix does indeed work:

https://github.com/vbenjs/vite-plugin-html/pull/96

@anncwb mind taking a look at the PR?

youthug commented 1 year ago

same problem, any updates?

alesdakshanin commented 1 year ago

Same problem here

snecker commented 1 year ago

Any update?

erg commented 1 year ago

This pr (https://github.com/vbenjs/vite-plugin-html/pull/96) solved it for me.

I am proxying port 8080 to a react backend on port 3000 with vite-plugin-html.

If I try my url on port 8080 from Chrome then the GET params are dropped by the vite proxy; they do not make it to the backend. If I use curl then it works as expected. As someone else mentioned, the problem is with Accept: text/html which Chrome sends by default and curl does not send. (Demo with fetch in the codebox below.)

Chrome 114.0.5735.133 sends Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 by default.

chrome browser url address:
  http://localhost:8080/proxy/lists/getListById.sql?listId=30747
backend sees:
  /proxy/lists/getListById.sql # WRONG

chrome browser url address:
  http://localhost:3000/proxy/lists/getListById.sql?listId=30747
backend sees:
  /proxy/lists/getListById.sql?listId=30747

# FAILS
fetch('http://localhost:8080/proxy/getListById.sql?listId=30747', {headers: {'Accept': 'text/html'}})
  .then(response => response.json())
  .then(data => console.log(data));

# WORKS
fetch('http://localhost:8080/proxy/getListById.sql?listId=30747', {headers: {'Accept': 'application/json'}})
  .then(response => response.json())
  .then(data => console.log(data));

# WORKS (no Accept header)
fetch('http://localhost:8080/proxy/getListById.sql?listId=30747')
  .then(response => response.json())
  .then(data => console.log(data));

# All three of the fetch calls work on port 3000

Applying the patch from https://github.com/vbenjs/vite-plugin-html/pull/96 solves this--port 8080 starts forwarding the GET params.

I'm not using the configureServer plugin.

The vite setup in question does not use anything weird:

import react from '@vitejs/plugin-react';
import 'dotenv/config.js';
import path from 'path';
import { defineConfig, splitVendorChunkPlugin } from 'vite';
import { createHtmlPlugin } from 'vite-plugin-html';

const REACT_APP_PATH_ROOT = process.env.REACT_APP_PATH_ROOT || '{{{REACT_APP_PATH_ROOT}}}';

export default defineConfig({
  server: {
    port: 8080,
    base: REACT_APP_PATH_ROOT,
    proxy: {
      '/proxy': `http://localhost:3000`
    }
  },
  plugins: [
    splitVendorChunkPlugin(),
    createHtmlPlugin({
      pages: [
        {
          inject: {
            data: {
              reactAppPathRootClean: REACT_APP_PATH_ROOT,
              reactAppPathRoot: REACT_APP_PATH_ROOT
            }
          }
        },
        {
          filename: path.resolve(__dirname, 'src/loginGoodbye.html')
        }
      ]
    }),
    react()
  ],

  ... // more config
}

Using "vite-plugin-html": "^3.2.0" and "vite": "^4.3.9".

If you want a minimal test project I could throw one together I suppose.

TLDR: please merge https://github.com/vbenjs/vite-plugin-html/pull/96

LvChengbin commented 1 year ago

How does such a terrible bug exist for years?

kilobyte2007 commented 1 year ago

@LvChengbin yep, frustrating. There are PRs to fix this but it looks like the repo is unmaintained. I'll probably have to fork it and release it on npm to use in our own project.

PeteTheHeat commented 2 months ago

I found this issue because I was seeing similar symptoms: vite-plugin-html was breaking my vite server proxy, specifically when I was using a Regex https://vitejs.dev/config/server-options.html#server-proxy

The solution was to patch the createRewire function here https://github.com/vbenjs/vite-plugin-html/blob/main/packages/core/src/htmlPlugin.ts#L357

 const isApiUrl = proxyUrlKeys.some((item) => {
        if (item.startsWith("^")){
          return new RegExp(item).test(pathname)
        }
        return pathname.startsWith(path.resolve(baseUrl, item))
      });