提交 419bec0b 编写于 作者: C Connor Davis 提交者: Tim Neutkens

Fix #5674 Append crossOrigin on the client side too, add config option for crossOrigin (#5873)

# Fixes https://github.com/zeit/next.js/issues/5674

This adds config option
```js
// next.config.js
module.exports = {
  crossOrigin: 'anonymous'
}
```
This config option is defined in the webpack Define Plugin at build.
`Head` and `NextScript` now use the config option, if it's not explicitly set on the element.
This value is now passed to Webpack so it can add it to scripts that it loads.
The value is now used in `PageLoader` (on the client) so it can add it to the scripts and links that it loads.
Using `<Head crossOrigin>` or `<NextScript crossOrigin>` is now deprecated.
上级 5e3bf6e5
# `Head` or `NextScript` attribute `crossOrigin` is deprecated
#### Why This Error Occurred
This option has been moved to `next.config.js`.
#### Possible Ways to Fix It
Add the config option:
```js
// next.config.js
module.exports = {
crossOrigin: 'anonymous'
}
```
### Useful Links
- [The issue this was reported in: #5674](https://github.com/zeit/next.js/issues/5674)
......@@ -1526,13 +1526,13 @@ module.exports = {
Note: Next.js will automatically use that prefix in the scripts it loads, but this has no effect whatsoever on `/static`. If you want to serve those assets over the CDN, you'll have to introduce the prefix yourself. One way of introducing a prefix that works inside your components and varies by environment is documented [in this example](https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration).
If your CDN is on a separate domain and you would like assets to be requested using a [CORS aware request](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) you can extend _document.js and specify the `crossOrigin` attribute on Head and NextScripts which is then used for all Next.js asset tags.
If your CDN is on a separate domain and you would like assets to be requested using a [CORS aware request](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) you can set a config option for that.
```js
<Head crossOrigin="anonymous">...</Head>
<body>
<Main/>
<NextScript crossOrigin="anonymous"/>
</body>
// next.config.js
module.exports = {
crossOrigin: 'anonymous'
}
```
## Production deployment
......
......@@ -258,6 +258,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer
// This saves chunks with the name given via `import()`
chunkFilename: isServer ? `${dev ? '[name]' : '[name].[contenthash]'}.js` : `static/chunks/${dev ? '[name]' : '[name].[contenthash]'}.js`,
strictModuleExceptionHandling: true,
crossOriginLoading: config.crossOrigin,
webassemblyModuleFilename: 'static/wasm/[modulehash].wasm'
},
performance: { hints: false },
......@@ -327,6 +328,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer
!dev && new webpack.HashedModuleIdsPlugin(),
// Removes server/client code by minifier
new webpack.DefinePlugin({
'process.crossOrigin': JSON.stringify(config.crossOrigin),
'process.browser': JSON.stringify(!isServer)
}),
// This is used in client/dev-error-overlay/hot-dev-client.js to replace the dist directory
......
......@@ -83,6 +83,7 @@ export default class PageLoader {
const script = document.createElement('script')
const url = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}`
script.crossOrigin = process.crossOrigin
script.src = url
script.onerror = () => {
const error = new Error(`Error when loading route: ${route}`)
......@@ -137,6 +138,7 @@ export default class PageLoader {
if (hasPreload) {
const link = document.createElement('link')
link.rel = 'preload'
link.crossOrigin = process.crossOrigin
link.href = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}`
link.as = 'script'
document.head.appendChild(link)
......
......@@ -61,7 +61,7 @@ export class Head extends Component {
nonce={this.props.nonce}
rel='stylesheet'
href={`${assetPrefix}/_next/${file}`}
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
......@@ -75,7 +75,7 @@ export class Head extends Component {
href={`${assetPrefix}/_next/${bundle.file}`}
as='script'
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
......@@ -98,7 +98,7 @@ export class Head extends Component {
rel='preload'
href={`${assetPrefix}/_next/${file}`}
as='script'
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
......@@ -117,14 +117,15 @@ export class Head extends Component {
}
return child
})
if (this.props.crossOrigin) console.warn('Warning: `Head` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated')
}
return <head {...this.props}>
{children}
{head}
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />}
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
{this.getPreloadDynamicChunks()}
{this.getPreloadMainLinks()}
{this.getCssLinks()}
......@@ -164,7 +165,7 @@ export class NextScript extends Component {
key={bundle.file}
src={`${assetPrefix}/_next/${bundle.file}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
......@@ -186,7 +187,7 @@ export class NextScript extends Component {
src={`${assetPrefix}/_next/${file}`}
nonce={this.props.nonce}
async
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
......@@ -201,14 +202,18 @@ export class NextScript extends Component {
const { page, buildId } = __NEXT_DATA__
const pagePathname = getPagePathname(page)
if (process.env.NODE_ENV !== 'production') {
if (this.props.crossOrigin) console.warn('Warning: `NextScript` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated')
}
return <Fragment>
{devFiles ? devFiles.map((file) => <script key={file} src={`${assetPrefix}/_next/${file}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />) : null}
{staticMarkup ? null : <script id="__NEXT_DATA__" type="application/json" nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} dangerouslySetInnerHTML={{
{devFiles ? devFiles.map((file) => <script key={file} src={`${assetPrefix}/_next/${file}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />) : null}
{staticMarkup ? null : <script id="__NEXT_DATA__" type="application/json" nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} dangerouslySetInnerHTML={{
__html: NextScript.getInlineScriptSource(this.context._documentProps)
}} />}
{page !== '/_error' && <script async id={`__NEXT_PAGE__${page}`} src={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />}
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
<script async id={`__NEXT_PAGE__/_error`} src={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
{page !== '/_error' && <script async id={`__NEXT_PAGE__${page}`} src={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
<script async id={`__NEXT_PAGE__/_error`} src={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
{staticMarkup ? null : this.getDynamicChunks()}
{staticMarkup ? null : this.getScripts()}
</Fragment>
......
module.exports = {
crossOrigin: 'anonymous'
}
......@@ -44,7 +44,7 @@ export default class MyDocument extends Document {
return (
<html>
<Head nonce='test-nonce' crossOrigin='anonymous'>
<Head nonce='test-nonce'>
{csp ? <meta httpEquiv='Content-Security-Policy' content={csp} /> : null}
<style>{`body { margin: 0 } /* custom! */`}</style>
</Head>
......@@ -52,7 +52,7 @@ export default class MyDocument extends Document {
<p id='custom-property'>{this.props.customProperty}</p>
<p id='document-hmr'>Hello Document HMR</p>
<Main />
<NextScript nonce='test-nonce' crossOrigin='anonymous' />
<NextScript nonce='test-nonce' />
</body>
</html>
)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册