Skip to content

Commit

Permalink
Fix rsc payload fetch failures due to state tree encoding (#51017)
Browse files Browse the repository at this point in the history
Encode the state tree where the content could contain unicode when
request the RSC payload, to avoid the fetch failure due to bad encoding
for headers

Fixes #48728
fix NEXT-1258
  • Loading branch information
huozhi committed Jun 9, 2023
1 parent 96e47d3 commit f19b31a
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
Expand Up @@ -37,7 +37,9 @@ export async function fetchServerResponse(
// Enable flight response
[RSC]: '1',
// Provide the current router state
[NEXT_ROUTER_STATE_TREE]: JSON.stringify(flightRouterState),
[NEXT_ROUTER_STATE_TREE]: encodeURIComponent(
JSON.stringify(flightRouterState)
),
}

/**
Expand Down
Expand Up @@ -23,7 +23,9 @@ export function parseAndValidateFlightRouterState(
}

try {
return flightRouterStateSchema.parse(JSON.parse(stateHeader))
return flightRouterStateSchema.parse(
JSON.parse(decodeURIComponent(stateHeader))
)
} catch {
throw new Error('The router state header was sent but could not be parsed.')
}
Expand Down
12 changes: 12 additions & 0 deletions test/e2e/app-dir/navigation/app/search-params/page.js
@@ -0,0 +1,12 @@
import Link from 'next/link'

export default function page({ searchParams }) {
return (
<div>
<p id="name">{searchParams.name ?? ''}</p>
<Link id="link" href="/">
home
</Link>
</div>
)
}
33 changes: 31 additions & 2 deletions test/e2e/app-dir/navigation/navigation.test.ts
@@ -1,6 +1,6 @@
import { createNextDescribe } from 'e2e-utils'
import webdriver from 'next-webdriver'
import { check } from 'next-test-utils'
import type { Request } from 'playwright-chromium'

createNextDescribe(
'app dir - navigation',
Expand All @@ -10,7 +10,7 @@ createNextDescribe(
({ next, isNextDev, isNextDeploy }) => {
describe('query string', () => {
it('should set query correctly', async () => {
const browser = await webdriver(next.url, '/')
const browser = await next.browser('/')
expect(await browser.elementById('query').text()).toMatchInlineSnapshot(
`""`
)
Expand All @@ -25,6 +25,35 @@ createNextDescribe(
const url = new URL(await browser.url())
expect(url.searchParams.toString()).toMatchInlineSnapshot(`"a=b&c=d"`)
})

it('should handle unicode search params', async () => {
const requests = []

const browser = await next.browser('/search-params?name=名')
browser.on('request', async (req: Request) => {
const res = await req.response()
requests.push([
new URL(req.url()).pathname,
res.ok(),
await res.headers(),
])
})
expect(await browser.elementById('name').text()).toBe('名')
await browser.elementById('link').click()

await check(async () => {
return requests.some((requestPair) => {
const [pathname, ok, headers] = requestPair
return (
pathname === '/' &&
ok &&
headers['content-type'] === 'text/x-component'
)
})
? 'success'
: JSON.stringify(requests)
}, 'success')
})
})

describe('hash', () => {
Expand Down

0 comments on commit f19b31a

Please sign in to comment.