Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Query parameters are lost in the URL when redirected by assigning the URL to window.location. #120

Open
Xooone47 opened this issue Jun 27, 2023 · 3 comments

Comments

@Xooone47
Copy link

Xooone47 commented Jun 27, 2023

Demo

https://codesandbox.io/p/sandbox/vite-plugin-html-redirect-demo-jhjqtn?file=%2Fvite.config.js

Reproduce steps

  1. Set server.proxy rules and use vite-plugin-html
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { createHtmlPlugin } from "vite-plugin-html";

export default defineConfig({
  plugins: [
    vue(),
    createHtmlPlugin({
      entry: "/src/main.js",
      template: "index.html",
    }),
  ],
  server: {
    cors: true,
    proxy: {
      "/api": {
        target: "https://www.baidu.com",
        changeOrigin: true,
        configure: (proxy, _options) => {
          proxy.on("proxyReq", function (proxyReq, req, res, options) {
            if (req.url.includes("/api")) {
              console.log("req.url", req.url);
              console.log("req.originalUrl", req.originalUrl);
              console.log("req._parsedUrl", req._parsedUrl);
            }
          });
        },
      },
    },
  },
});
  1. Assign a URL (/api/login?redirect=mockUrl) to window.location.href when clicking the Redirect button
<script setup>
const url = "/api/login?redirect=mockUrl";

const onFetch = async () => {
  try {
    const res = await fetch(url);
    console.log(res);
  } catch (e) {
    console.error("fetch e", e);
  }
};

const onRedirect = () => {
  window.location.href = url;
};
</script>

<template>
  <div>
    <div class="card">
      <button type="button" @click="onFetch">Fetch</button>
      <button type="button" @click="onRedirect">Redirect</button>
    </div>
  </div>
</template>
  1. Losing the query params in request
    image

On the console, we can see the originalUrl that was requested is /api/login?redirect=mockUrl , but it becomes /api/login after being handled by the proxy middleware.

And the URL is correct when we click the Fetch button to trigger a xhr request.

image

Reason

code

// https://github.com/vbenjs/vite-plugin-html/blob/main/packages/core/src/htmlPlugin.ts#L87-L93
server.middlewares.use(
    history({
      disableDotRule: undefined,
      htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
      rewrites: rewrites,
    }),
)

// https://github.com/vbenjs/vite-plugin-html/blob/main/packages/core/src/htmlPlugin.ts#L331
function createRewire(
  reg: string,
  page: any,
  baseUrl: string,
  proxyUrlKeys: string[],
) {
  return {
    from: new RegExp(`^/${reg}*`),
    to({ parsedUrl }: any) {
      const pathname: string = parsedUrl.pathname

      const excludeBaseUrl = pathname.replace(baseUrl, '/')

      const template = path.resolve(baseUrl, page.template)

      if (excludeBaseUrl === '/') {
        return template
      }
      const isApiUrl = proxyUrlKeys.some((item) =>
        pathname.startsWith(path.resolve(baseUrl, item)),
      )
      return isApiUrl ? excludeBaseUrl : template
    },
  }
}

The vite-plugin-html adds a proxy handling rule for text/html type request, and uses parsedUrl.pathname which doesn't contain query params (pic below) as the path to redirect. So the problem occurs when starts a document request but the xhr requests is good.

image

@jonay1
Copy link

jonay1 commented Aug 2, 2023

up up up

@jseto
Copy link

jseto commented Aug 22, 2023

Actually, when createHtmlPlugin is enabled, any route is ignored and only the root path is rendered.
This happens even with the public folder.

As a quick test:

  • place favicon.png in public folder
  • In the browser navigate to http:localhost:8080/favicon.png
    The application is loaded in the browser instead of the image.

@wojtekmaj
Copy link

wojtekmaj commented Nov 25, 2023

Try vite-plugin-simple-html.
It has fewer features, but as a result, far less magic required. I developed it specifically to cover my needs while not be affected by this bug, which was a blocker for me migrating to Vite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants