Add cookies and headers for request using in RSC (#31623)
* Passdown the request with richer information * test: access request header as prop from gSSP
This commit is contained in:
parent
91e8620376
commit
7f58a2e49f
5 changed files with 47 additions and 17 deletions
|
@ -2,6 +2,11 @@ import { NextRequest } from '../../../../server/web/spec-extension/request'
|
|||
import { renderToHTML } from '../../../../server/web/render'
|
||||
import RenderResult from '../../../../server/render-result'
|
||||
|
||||
const createHeaders = (args?: any) => ({
|
||||
...args,
|
||||
'x-middleware-ssr': '1',
|
||||
})
|
||||
|
||||
export function getRender({
|
||||
App,
|
||||
Document,
|
||||
|
@ -24,15 +29,15 @@ export function getRender({
|
|||
restRenderOpts: any
|
||||
}) {
|
||||
return async function render(request: NextRequest) {
|
||||
const url = request.nextUrl
|
||||
const { nextUrl: url, cookies, headers } = request
|
||||
const { pathname, searchParams } = url
|
||||
|
||||
const query = Object.fromEntries(searchParams)
|
||||
|
||||
// Preflight request
|
||||
if (request.method === 'HEAD') {
|
||||
return new Response('OK.', {
|
||||
headers: { 'x-middleware-ssr': '1' },
|
||||
return new Response(null, {
|
||||
headers: createHeaders(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -41,7 +46,11 @@ export function getRender({
|
|||
: false
|
||||
delete query.__flight__
|
||||
|
||||
const req = { url: pathname }
|
||||
const req = {
|
||||
url: pathname,
|
||||
cookies,
|
||||
headers,
|
||||
}
|
||||
const renderOpts = {
|
||||
...restRenderOpts,
|
||||
// Locales are not supported yet.
|
||||
|
@ -103,7 +112,7 @@ export function getRender({
|
|||
).toString(),
|
||||
{
|
||||
status: 500,
|
||||
headers: { 'x-middleware-ssr': '1' },
|
||||
headers: createHeaders(),
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -114,7 +123,7 @@ export function getRender({
|
|||
'An error occurred while rendering ' + pathname + '.',
|
||||
{
|
||||
status: 500,
|
||||
headers: { 'x-middleware-ssr': '1' },
|
||||
headers: createHeaders(),
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -126,7 +135,7 @@ export function getRender({
|
|||
} as any)
|
||||
|
||||
return new Response(transformStream.readable, {
|
||||
headers: { 'x-middleware-ssr': '1' },
|
||||
headers: createHeaders(),
|
||||
status: 200,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -688,13 +688,14 @@ if (process.env.__NEXT_RSC) {
|
|||
}
|
||||
|
||||
RSCComponent = (props: any) => {
|
||||
const { asPath: cacheKey } = useRouter() as any
|
||||
const cacheKey = useRouter().asPath
|
||||
const { __flight_serialized__, __flight_fresh__ } = props
|
||||
return (
|
||||
<React.Suspense fallback={null}>
|
||||
<RSCWrapper
|
||||
cacheKey={cacheKey}
|
||||
serialized={(props as any).__flight_serialized__}
|
||||
_fresh={(props as any).__flight_fresh__}
|
||||
serialized={__flight_serialized__}
|
||||
_fresh={__flight_fresh__}
|
||||
/>
|
||||
</React.Suspense>
|
||||
)
|
||||
|
|
|
@ -1002,7 +1002,7 @@ export async function renderToHTML(
|
|||
|
||||
if (renderServerComponentData) {
|
||||
const stream: ReadableStream = renderToReadableStream(
|
||||
<OriginalComponent {...props} />,
|
||||
<OriginalComponent {...props.pageProps} />,
|
||||
serverComponentManifest
|
||||
)
|
||||
const reader = stream.getReader()
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
import Foo from '../components/foo.client'
|
||||
|
||||
const envVar = process.env.ENV_VAR_TEST
|
||||
const headerKey = 'x-next-test-client'
|
||||
|
||||
export default function Index() {
|
||||
export default function Index({ header, router }) {
|
||||
return (
|
||||
<div>
|
||||
<h1>{`thisistheindexpage.server`}</h1>
|
||||
<div>{envVar}</div>
|
||||
<h1>{`component:index.server`}</h1>
|
||||
<div>{'path:' + router.pathname}</div>
|
||||
<div>{'env:' + envVar}</div>
|
||||
<div>{'header:' + header}</div>
|
||||
<div>
|
||||
<Foo />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function getServerSideProps({ req }) {
|
||||
const { headers } = req
|
||||
const header = headers.get(headerKey)
|
||||
|
||||
return {
|
||||
props: {
|
||||
header,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,7 +216,11 @@ runSuite('document', 'prod', documentSuite)
|
|||
async function runBasicTests(context, env) {
|
||||
const isDev = env === 'dev'
|
||||
it('should render the correct html', async () => {
|
||||
const homeHTML = await renderViaHTTP(context.appPort, '/')
|
||||
const homeHTML = await renderViaHTTP(context.appPort, '/', null, {
|
||||
headers: {
|
||||
'x-next-test-client': 'test-util',
|
||||
},
|
||||
})
|
||||
|
||||
// should have only 1 DOCTYPE
|
||||
expect(homeHTML).toMatch(/^<!DOCTYPE html><html/)
|
||||
|
@ -238,8 +242,10 @@ async function runBasicTests(context, env) {
|
|||
'/this-is-not-found'
|
||||
)
|
||||
|
||||
expect(homeHTML).toContain('thisistheindexpage.server')
|
||||
expect(homeHTML).toContain('env_var_test')
|
||||
expect(homeHTML).toContain('component:index.server')
|
||||
expect(homeHTML).toContain('env:env_var_test')
|
||||
expect(homeHTML).toContain('header:test-util')
|
||||
expect(homeHTML).toContain('path:/')
|
||||
expect(homeHTML).toContain('foo.client')
|
||||
|
||||
expect(dynamicRouteHTML1).toContain('[pid]')
|
||||
|
|
Loading…
Reference in a new issue