Skip to content

Commit

Permalink
Use browser navigation when RSC payload fails to fetch (#46674)
Browse files Browse the repository at this point in the history
Fixes #43605
Fixes NEXT-325
Fixes NEXT-193

This ensures that when the `fetch()` for the RSC payload gets redirected
server-side to a URL that fails CORS (e.g. an external url). This
catches the error and returns the url that was fetches to be
hard-navigated. This also covers other cases like when the host can't be
reached.

Added a note to add a test for this later as it depends on having a
deployment without CORS.

<!--
Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:
-->

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
timneutkens and kodiakhq[bot] committed Mar 4, 2023
1 parent f2989f7 commit 5aa9bc8
Showing 1 changed file with 28 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,35 @@ export async function fetchServerResponse(
headers[NEXT_ROUTER_PREFETCH] = '1'
}

const res = await fetch(url.toString(), {
// Backwards compat for older browsers. `same-origin` is the default in modern browsers.
credentials: 'same-origin',
headers,
})
const canonicalUrl = res.redirected
? urlToUrlWithoutFlightMarker(res.url)
: undefined
try {
const res = await fetch(url.toString(), {
// Backwards compat for older browsers. `same-origin` is the default in modern browsers.
credentials: 'same-origin',
headers,
})
const canonicalUrl = res.redirected
? urlToUrlWithoutFlightMarker(res.url)
: undefined

const isFlightResponse =
res.headers.get('content-type') === RSC_CONTENT_TYPE_HEADER
const isFlightResponse =
res.headers.get('content-type') === RSC_CONTENT_TYPE_HEADER

// If fetch returns something different than flight response handle it like a mpa navigation
if (!isFlightResponse) {
return [res.url, undefined]
}
// If fetch returns something different than flight response handle it like a mpa navigation
if (!isFlightResponse) {
return [res.url, undefined]
}

// Handle the `fetch` readable stream that can be unwrapped by `React.use`.
const flightData: FlightData = await createFromFetch(Promise.resolve(res))
return [flightData, canonicalUrl]
// Handle the `fetch` readable stream that can be unwrapped by `React.use`.
const flightData: FlightData = await createFromFetch(Promise.resolve(res))
return [flightData, canonicalUrl]
} catch (err) {
console.error(
'Failed to fetch RSC payload. Falling back to browser navigation.',
err
)
// If fetch fails handle it like a mpa navigation
// TODO-APP: Add a test for the case where a CORS request fails, e.g. external url redirect coming from the response.
// See https://github.com/vercel/next.js/issues/43605#issuecomment-1451617521 for a reproduction.
return [url.toString(), undefined]
}
}

0 comments on commit 5aa9bc8

Please sign in to comment.