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

fix(build): add crossorigin attribute to link[rel="stylesheet"] #12991

Merged
merged 2 commits into from
Oct 18, 2023

Conversation

Priestch
Copy link
Contributor

Description

Add crossorigin attribute to CSS link tag when cssCodeSplit not enable, to make the CSS file can be host on CDN.

Additional context

I'm not sure whether crossorigin attribute should be added to

rel: 'stylesheet',


What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines and follow the PR Title Convention.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.

@stackblitz
Copy link

stackblitz bot commented Apr 25, 2023

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@patak-dev
Copy link
Member

This sounds good to me, as we are already adding it for <script>. I'll add the issue for discussion in a team meeting and to the Vite 5 timeline. I think we should also have it in vite/packages/vite/src/node/plugins/html.ts as you proposed.

@patak-dev patak-dev added feat: css feat: build p3-minor-bug An edge case that only affects very specific usage (priority) labels Jul 19, 2023
@patak-dev patak-dev added this to the 5.0 milestone Jul 19, 2023
@bluwy
Copy link
Member

bluwy commented Oct 14, 2023

I also think this looks fine to me and shouldn't impact much of existing setups today. Also agree that we add crossorigin: true for the other css tag too.

patak-dev
patak-dev previously approved these changes Oct 18, 2023
@sapphi-red sapphi-red changed the title fix(build): add crossorigin attribute to link when cssCodeSplit not enable fix(build): add crossorigin attribute to link[rel="stylesheet"] Oct 18, 2023
@sapphi-red sapphi-red merged commit 6e7b25c into vitejs:main Oct 18, 2023
11 checks passed
@devdubby
Copy link

@Priestch
Hello. Thank you for your work. My project is using vite5 version and i upload css to external CDN to request and get response from browser.
Due to your code addition, the css is requested with crossorigin attribute, but due to browser caching, after few requests, it turns into no-cors request and I am facing the issue that crossorigin attribute and no-cors request are mixed. It's an external CDN, so I can't modify the cache policy either, has anyone else experienced this?

@Priestch
Copy link
Contributor Author

@devdubby What's the problem of mixed request? I think maybe it's an issue related to the browser, do you have a link can reproduced the issue? I'm very curious.

@devdubby
Copy link

devdubby commented May 29, 2024

@Priestch
There is no link that can be reproduced because it is difficult to disclose the issue outside the company project. To list the issue situation (below is a situation that occurred in Chrome browser)

  1. Visit the website built with vite. At this time, you will receive js, css, etc. uploaded to the CDN.
  2. Until the CDN request is cached, the css is well received.
  3. About... If you repeat a 5 to 6 reload, the css crossorgin request will be
    Access to CSS stylesheet at 'https://cdn-linkt/index-test.css' from origin 'https://my-project-address.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. This error occurs.
  4. If you enable the Disable cache in the Chrome Developer Tool, you will receive the css file from cdn again soon.

I asked the team developing the CDN, and in this case, the cors policy issue can be caused by the mixture of the cors request and the browser cached no-cors request. (There is nothing wrong with the request and response in the CDN.)

Have you had any experience like this? I'm writing this comment because I want to get a little bit of your insight. Thank you for your time.

@Priestch
Copy link
Contributor Author

Priestch commented May 29, 2024

@devdubby I add the crossorigin attribute to use CSS with CDN, I checked and it works as expected.

I'm sorry and have no idea about the problem, but I found a similar article I found a similar article https://anthonymineo.com/solving-a-cors-issue-when-serving-from-chromes-browser-cache/, hope it helps.

@fallemand
Copy link
Contributor

fallemand commented Aug 23, 2024

@Priestch There is no link that can be reproduced because it is difficult to disclose the issue outside the company project. To list the issue situation (below is a situation that occurred in Chrome browser)

  1. Visit the website built with vite. At this time, you will receive js, css, etc. uploaded to the CDN.
  2. Until the CDN request is cached, the css is well received.
  3. About... If you repeat a 5 to 6 reload, the css crossorgin request will be
    Access to CSS stylesheet at 'https://cdn-linkt/index-test.css' from origin 'https://my-project-address.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. This error occurs.
  4. If you enable the Disable cache in the Chrome Developer Tool, you will receive the css file from cdn again soon.

I asked the team developing the CDN, and in this case, the cors policy issue can be caused by the mixture of the cors request and the browser cached no-cors request. (There is nothing wrong with the request and response in the CDN.)

Have you had any experience like this? I'm writing this comment because I want to get a little bit of your insight. Thank you for your time.

We are facing the same issue. After Migrating to vite5, the css links contains crossorigin.
Fetching from the CDN works perfect most of the time, but randomly, we get:

Access to CSS stylesheet at 'https://cdn.getyourguide.com/tf/assets/compiled/client/assets/css-slider-card-CMnb0hfz-v2... 'from origin 'https://www.getyourguide.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

@fallemand
Copy link
Contributor

fallemand commented Aug 23, 2024

The issue seems to be that we are mixing request with crossorigin and without crossorigin.

<link rel="stylesheet" crossorigin src="cdn.blabla.test/some-css-123123.css">
<link rel="stylesheet" src="cdn.blabla.test/some-css-123123.css">

For us, this seems to happen because on some pages, the Vue component is used async (async import(...)), and on others, we import it directly.
This produces imports with different crossorigin values, and once we cache a value without crossorigin, and later, the browser tries to use it with crossorigin, it fails.

@Priestch, could it be that we are missing some where to add the crossorigin? Maybe related to async imports, or a plugin. For example here we don't add crossorigin: Link, but not sure what is this.

@Priestch
Copy link
Contributor Author

could it be that we are missing some where to add the crossorigin? Maybe related to async imports, or a plugin. For example here we don't add crossorigin: Link, but not sure what is this.

@fallemand I think the async import failed to add the crossorigin, one of my teammate use a custom plugin to hack this, it replace the default export const preloadHelperId = '\0vite/preload-helper.js'.

    // ...
    transform(code, id) {
      if (id.endsWith('vite/preload-helper')) {
        return vitePreloadHelperCode;
      }
      return code;
    },
    // ...

@fallemand
Copy link
Contributor

fallemand commented Aug 24, 2024

Nice, thanks. I created an issue, and will follow up with a PR.

Here is the temp solution:

import type { PluginOption } from "vite";

export default function cssCrossoriginPreload(): PluginOption {
  return {
    name: "css-crossorigin-plugin",
    transform(code, id) {
      if (id.endsWith("vite/preload-helper.js")) {
        const searchValue = "if (!isCss) {";
        const replaceValue = `if (isCss) link.crossOrigin = '';${searchValue}`;
        if (!code.includes(searchValue)) {
          throw new Error(`Failed to path Vite "vite/preload-helper.js"`);
        }
        const patchedCode = code.replace(searchValue, replaceValue);
        return {
          code: patchedCode,
          map: null,
        };
      }
      return null;
    },
  };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: build feat: css p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants