preload-webpack-plugin icon indicating copy to clipboard operation
preload-webpack-plugin copied to clipboard

New config option to opt-in to crossorigin="anonymous"

Open macoshita opened this issue 6 years ago • 6 comments

Amazon S3 not send CORS headers if use <link rel="prefetch"> without crossorigin attribute. This response is cached by Chrome, and reuse next access by script tag. So this script is blocked by CORS policy.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="initial-scale=1">
  <title>crossorigin test</title>
  <link rel="prefetch" href="https://s3-ap-northeast-1.amazonaws.com/macoshita-test-crossorigin/main.js">
</head>
<body>
  <h1>crossorigin prefetch test (maybe fail)</h1>
  <a id="test" href="javascript:void(0)">Click to load script</a>
  <script>
    document.getElementById('test').addEventListener('click', function () {
      const script = document.createElement('script')
      script.src = 'https://s3-ap-northeast-1.amazonaws.com/macoshita-test-crossorigin/main.js'
      script.crossOrigin = 'crossorigin'

      // will be blocked
      document.getElementsByTagName('head')[0].appendChild(script)
    }, false)
  </script>
</body>
</html>

macoshita avatar Apr 17 '18 07:04 macoshita

It would definitely break things if we unconditionally added the crossorigin="anonymous" attribute to all <link> tags, or all <link> tags for script resources. Any third-party script that is hosted on a server that doesn't support CORS would trigger an error.

It could be possible to allow that attribute to be added conditionally for script resources if you opt-in via a config settings if it's really needed.

But, taken a step back, are you sure that you need to opt-in to CORS mode for that particular script resource? In general, the primary reason to opt-in to CORS when loading third-party scripts is to get access to more detailed stack traces. Using CORS for script resources isn't a technical requirement, like it is for font resources. (In other words, an opaque response can be used as a script resource on a page.)

If you were to remove the

script.crossOrigin = 'crossorigin'

from your sample app, things would work as expected, other than the lack of transparency into stack traces originating in the third-party script.

jeffposnick avatar Apr 18 '18 14:04 jeffposnick

Any third-party script that is hosted on a server that doesn't support CORS would trigger an error.

That's right, I was wrong. As you say, it is correct to allow opt-in via a config settings.

I need it for stack trace of third-party scripts. In my site, HTML domain and JS domain are different. Please consider to add of option.

macoshita avatar Apr 19 '18 03:04 macoshita

What if you are serving a script files from a CDN. and you want to preload a webpack dynamic import? Wouldn't you need crossorigin in that scenario?

do you have any guidelines on the implementation? either way I am happy to submit a PR if there is interest.

Thanks!

joeuy avatar Jul 20 '18 00:07 joeuy

"What if you are serving a script files from a CDN. and you want to preload a webpack dynamic import? Wouldn't you need crossorigin in that scenario?"

@joeuy did you get the solution you asked above? I am kinda stuck there .

mt-dileep avatar Jan 04 '20 11:01 mt-dileep

I'm using the same setup as @joeuy, getting my assets from a CDN (aws s3) would really appreciate this in order to resolve:

A preload <link> was found for "https://mydomain.com/static/css/10.bb62e669e50e63b859aa.css" but was not used by the browser. Check that you are using the `crossorigin` attribute properly.

ssolders avatar Mar 18 '20 09:03 ssolders

UPDATE: it seems that I have the same issue #93

I'm getting the same message from lighthouse for same-domain css!

Am I doing something wrong here?

// HTML generated by HtmlWebpackPlugin
<link as="style" href="/main.551e4bcaef73e8209662.css" rel="preload">
// Lighthouse message
A preload <link> was found for "http://localhost:5005/main.551e4bcaef73e8209662.css" 
but was not used by the browser. Check that you are using the `crossorigin` attribute properly.
//webpack config
      new PreloadWebpackPlugin({
        rel: 'preload',
        include: ['main']
      }),

PS: I do have some googlefont styles at the top of the doc with crossorigin option -- in case it matters here

mwmcode avatar Aug 17 '20 11:08 mwmcode