mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Add crossOrigin via props to _document Head and NextScript (#5646)
This alternative implementation of https://github.com/zeit/next.js/pull/5150 follows @timneutkens suggestion of using props. Fixes #5150 Fixes #3630
This commit is contained in:
parent
e8f7847645
commit
4ce095df89
|
@ -1484,6 +1484,14 @@ 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.
|
||||
```js
|
||||
<Head crossOrigin="anonymous">...</Head>
|
||||
<body>
|
||||
<Main/>
|
||||
<NextScript crossOrigin="anonymous"/>
|
||||
</body>
|
||||
```
|
||||
## Production deployment
|
||||
|
||||
To deploy, instead of running `next`, you want to build for production usage ahead of time. Therefore, building and starting are separate commands:
|
||||
|
|
|
@ -40,7 +40,8 @@ export class Head extends Component {
|
|||
}
|
||||
|
||||
static propTypes = {
|
||||
nonce: PropTypes.string
|
||||
nonce: PropTypes.string,
|
||||
crossOrigin: PropTypes.string
|
||||
}
|
||||
|
||||
getCssLinks () {
|
||||
|
@ -60,6 +61,7 @@ export class Head extends Component {
|
|||
nonce={this.props.nonce}
|
||||
rel='stylesheet'
|
||||
href={`${assetPrefix}/_next/${file}`}
|
||||
crossOrigin={this.props.crossOrigin}
|
||||
/>
|
||||
})
|
||||
}
|
||||
|
@ -73,6 +75,7 @@ export class Head extends Component {
|
|||
href={`${assetPrefix}/_next/${bundle.file}`}
|
||||
as='script'
|
||||
nonce={this.props.nonce}
|
||||
crossOrigin={this.props.crossOrigin}
|
||||
/>
|
||||
})
|
||||
}
|
||||
|
@ -95,6 +98,7 @@ export class Head extends Component {
|
|||
rel='preload'
|
||||
href={`${assetPrefix}/_next/${file}`}
|
||||
as='script'
|
||||
crossOrigin={this.props.crossOrigin}
|
||||
/>
|
||||
})
|
||||
}
|
||||
|
@ -117,9 +121,9 @@ export class Head extends Component {
|
|||
|
||||
return <head {...this.props}>
|
||||
{head}
|
||||
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} />}
|
||||
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} as='script' nonce={this.props.nonce} />
|
||||
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} as='script' nonce={this.props.nonce} />
|
||||
{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} />
|
||||
{this.getPreloadDynamicChunks()}
|
||||
{this.getPreloadMainLinks()}
|
||||
{this.getCssLinks()}
|
||||
|
@ -148,7 +152,8 @@ export class NextScript extends Component {
|
|||
}
|
||||
|
||||
static propTypes = {
|
||||
nonce: PropTypes.string
|
||||
nonce: PropTypes.string,
|
||||
crossOrigin: PropTypes.string
|
||||
}
|
||||
|
||||
getDynamicChunks () {
|
||||
|
@ -158,7 +163,8 @@ export class NextScript extends Component {
|
|||
async
|
||||
key={bundle.file}
|
||||
src={`${assetPrefix}/_next/${bundle.file}`}
|
||||
nonce={this.props.nonce}
|
||||
nonce={this.props.nonce}
|
||||
crossOrigin={this.props.crossOrigin}
|
||||
/>
|
||||
})
|
||||
}
|
||||
|
@ -180,6 +186,7 @@ export class NextScript extends Component {
|
|||
src={`${assetPrefix}/_next/${file}`}
|
||||
nonce={this.props.nonce}
|
||||
async
|
||||
crossOrigin={this.props.crossOrigin}
|
||||
/>
|
||||
})
|
||||
}
|
||||
|
@ -195,13 +202,13 @@ export class NextScript extends Component {
|
|||
const pagePathname = getPagePathname(page)
|
||||
|
||||
return <Fragment>
|
||||
{devFiles ? devFiles.map((file) => <script key={file} src={`${assetPrefix}/_next/${file}`} nonce={this.props.nonce} />) : null}
|
||||
{staticMarkup ? null : <script id="__NEXT_DATA__" type="application/json" nonce={this.props.nonce} dangerouslySetInnerHTML={{
|
||||
{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={{
|
||||
__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} />}
|
||||
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} nonce={this.props.nonce} />
|
||||
<script async id={`__NEXT_PAGE__/_error`} src={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} nonce={this.props.nonce} />
|
||||
{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} />
|
||||
{staticMarkup ? null : this.getDynamicChunks()}
|
||||
{staticMarkup ? null : this.getScripts()}
|
||||
</Fragment>
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class MyDocument extends Document {
|
|||
|
||||
return (
|
||||
<html>
|
||||
<Head nonce='test-nonce'>
|
||||
<Head nonce='test-nonce' crossOrigin='anonymous'>
|
||||
{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' />
|
||||
<NextScript nonce='test-nonce' crossOrigin='anonymous' />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
|
|
@ -35,6 +35,14 @@ export default function ({ app }, suiteName, render, fetch) {
|
|||
expect(noncesAdded).toBe(true)
|
||||
})
|
||||
|
||||
test('It adds crossOrigin to all scripts and preload links', async () => {
|
||||
const $ = await get$('/')
|
||||
const crossOrigin = 'anonymous'
|
||||
$('script, link[rel=preload]').each((index, element) => {
|
||||
expect($(element).attr('crossorigin') === crossOrigin).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
test('It renders ctx.renderPage with enhancer correctly', async () => {
|
||||
const $ = await get$('/?withEnhancer=true')
|
||||
const nonce = 'RENDERED'
|
||||
|
|
Loading…
Reference in a new issue