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:
Jiachi Liu 2021-11-22 19:53:22 +01:00 committed by GitHub
parent 91e8620376
commit 7f58a2e49f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 17 deletions

View file

@ -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,
})
}

View file

@ -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>
)

View file

@ -1002,7 +1002,7 @@ export async function renderToHTML(
if (renderServerComponentData) {
const stream: ReadableStream = renderToReadableStream(
<OriginalComponent {...props} />,
<OriginalComponent {...props.pageProps} />,
serverComponentManifest
)
const reader = stream.getReader()

View file

@ -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,
},
}
}

View file

@ -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]')