vitejs / vite

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

allow use-credentials of crossorigin attribute #6648

Open CedricHildbrand opened 2 years ago

CedricHildbrand commented 2 years ago

Clear and concise description of the problem

When building, the script tags inside the dist index.html get the attribute crossorigin automatically. The only way to change it to "use-credentials" is by modifying the final dist file. The reason this should be able to be modified is because there is a bug in Safari which leads to an 401 HTTP error if you have any authentication. https://bugs.webkit.org/show_bug.cgi?id=171566

Suggested solution

It would be nice to set crossorigin="use-credentials" inside vite.config.js somewhere for modules.

Alternative

No response

Additional context

No response

Validations

sapphi-red commented 2 years ago

related: #4453

bluwy commented 2 years ago

I'm not sure about allowing another set of config to workaround a browser bug, since the issue has been 2 years and counting, perhaps it's fine to follow the correct spec instead. Another solution is to check build.target for a safari version and set use-credentials accordingly.

JSFiend commented 1 year ago

create a vite plugin to replace

function useCredentials() {
  return {
    name: 'use-credentials',
    transformIndexHtml(html: string) {
      return html.replace(
        'crossorigin',
        'crossorigin="use-credentials"',
      );
    },
  };
ketulm commented 1 year ago

There is a similar issue on Firefox.

The above plugin workaround wouldn't work for <link> tags added by html.ts for pre-loading the bundle. The modulepreload polyfill on Firefox defaults to anonymous credentials for these pre-load links.

It'd be good to handle non-chrome browsers in the polyfill or add a vite option to allow explicitly setting the crossorigin attribute.

Are there any plans to address this soon? Our production builds are affected by this. Currently, working around it with forked Vite with html.ts patched alongside the #13136 feature.

electrovir commented 1 year ago

create a vite plugin to replace

function useCredentials() {
  return {
    name: 'use-credentials',
    transformIndexHtml(html: string) {
      return html.replace(
        'crossorigin',
        'crossorigin="use-credentials"',
      );
    },
  };

I was looking for a way to remove the crossorigin attribute entirely and this helped a lot, thanks!

ikeq commented 5 months ago

The solution addressed by @JSFiend will not work for lazy loaded modules (via import()).

image

Source code:

https://github.com/vitejs/vite/blob/eef9da13d0028161eacc0ea699988814f29a56e4/packages/vite/src/node/plugins/importAnalysisBuild.ts#L116

Still need an official solution @bluwy

ikeq commented 5 months ago

Came up with this temporary workaround

export default defineConfig({
  plugins: [
    {
      name: 'crossorigin',
      transformIndexHtml(html) {
        return html.replace(/crossorigin/g, 'crossorigin="use-credentials"');
      },
    },
    {
      generateBundle(options, bundle) {
        for (const url in bundle) {
          // 2. Then replace `crossOrigin`
          if (bundle[url].name === 'helper') {
            bundle[url].code = bundle[url].code.replace(
              'crossOrigin=""',
              'crossOrigin="use-credentials"'
            );
          }
        }
      },
    },
  ],
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          // 1. Split vite scripts into a separate chunk
          if (id.startsWith('\u0000vite')) {
            return 'helper';
          }
        },
      },
    },
  },
});
front-refined commented 1 month ago

想出了这个临时解决办法

export default defineConfig({
  plugins: [
    {
      name: 'crossorigin',
      transformIndexHtml(html) {
        return html.replace(/crossorigin/g, 'crossorigin="use-credentials"');
      },
    },
    {
      generateBundle(options, bundle) {
        for (const url in bundle) {
          // 2. Then replace `crossOrigin`
          if (bundle[url].name === 'helper') {
            bundle[url].code = bundle[url].code.replace(
              'crossOrigin=""',
              'crossOrigin="use-credentials"'
            );
          }
        }
      },
    },
  ],
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          // 1. Split vite scripts into a separate chunk
          if (id.startsWith('\u0000vite')) {
            return 'helper';
          }
        },
      },
    },
  },
});

nice :+1: I made a change based on this, others can also refer to it

plugins: [
  {
    name: 'vite:crossorigin-use-credentials',
    transformIndexHtml(html) {
      return html.replace(/crossorigin/g, 'crossorigin="use-credentials"');
    },
    generateBundle(_, bundle) {
      for (const url in bundle) {
        if (bundle[url].name === 'preload-helper') {
          // @ts-ignore
          bundle[url].code = bundle[url].code.replace(
            'crossOrigin = ""',
            'crossOrigin = "use-credentials"'
          );
        }
      }
    }
  }
],
build: {
  rollupOptions: {
    output: {
      manualChunks(id) {
        // Extract virtual module
        if (id === '\0vite/preload-helper.js') {
          return 'preload-helper';
        }
      }
    }
  }
}