Remove deprecation for relative URL usage in middlewares (#34461)
* Remove deprecation for relative URL usage in middlewares * fix tests Co-authored-by: JJ Kasper <jj@jjsweb.site>
This commit is contained in:
parent
d4d79b2d9b
commit
f0f322c0d1
4 changed files with 38 additions and 19 deletions
|
@ -2,11 +2,11 @@
|
|||
|
||||
#### Why This Error Occurred
|
||||
|
||||
You are using a Middleware function that uses `Response.redirect(url)`, `NextResponse.redirect(url)` or `NextResponse.rewrite(url)` where `url` is a relative or an invalid URL. Currently this will work, but building a request with `new Request(url)` or running `fetch(url)` when `url` is a relative URL will **not** work. For this reason and to bring consistency to Next.js Middleware, this behavior will be deprecated soon in favor of always using absolute URLs.
|
||||
You are using a Middleware function that uses `Response.redirect(url)`, `NextResponse.redirect(url)` or `NextResponse.rewrite(url)` where `url` is a relative or an invalid URL. Prior to Next.js 12.1, we allowed passing relative URLs. However, constructing a request with `new Request(url)` or running `fetch(url)` when `url` is a relative URL **does not** work. For this reason and to bring consistency to Next.js Middleware, this behavior has been deprecated and now removed.
|
||||
|
||||
#### Possible Ways to Fix It
|
||||
|
||||
To fix this warning you must always pass absolute URL for redirecting and rewriting. There are several ways to get the absolute URL but the recommended way is to clone `NextURL` and mutate it:
|
||||
To fix this error you must always pass absolute URL for redirecting and rewriting. There are several ways to get the absolute URL but the recommended way is to clone `NextURL` and mutate it:
|
||||
|
||||
```typescript
|
||||
import type { NextRequest } from 'next/server'
|
||||
|
|
|
@ -149,18 +149,16 @@ export function splitCookiesString(cookiesString: string) {
|
|||
}
|
||||
|
||||
/**
|
||||
* We will be soon deprecating the usage of relative URLs in Middleware introducing
|
||||
* URL validation. This helper puts the future code in place and prints a warning
|
||||
* for cases where it will break. Meanwhile we preserve the previous behavior.
|
||||
* Validate the correctness of a user-provided URL.
|
||||
*/
|
||||
export function validateURL(url: string | URL): string {
|
||||
try {
|
||||
return String(new URL(String(url)))
|
||||
} catch (error: any) {
|
||||
console.log(
|
||||
`warn -`,
|
||||
'using relative URLs for Middleware will be deprecated soon - https://nextjs.org/docs/messages/middleware-relative-urls'
|
||||
throw new Error(
|
||||
`URLs is malformed. Please use only absolute URLs - https://nextjs.org/docs/messages/middleware-relative-urls`,
|
||||
// @ts-expect-error This will work for people who enable the error causes polyfill
|
||||
{ cause: error }
|
||||
)
|
||||
return String(url)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ export async function middleware(request) {
|
|||
) {
|
||||
const isExternal = url.searchParams.get('override') === 'external'
|
||||
return NextResponse.rewrite(
|
||||
isExternal ? 'https://vercel.com' : '/rewrites/a'
|
||||
isExternal ? 'https://vercel.com' : new URL('/rewrites/a', request.url)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ const context = {}
|
|||
context.appDir = join(__dirname, '../')
|
||||
|
||||
const middlewareWarning = 'using beta Middleware (not covered by semver)'
|
||||
const urlsWarning = 'using relative URLs for Middleware will be deprecated soon'
|
||||
const urlsError = 'Please use only absolute URLs'
|
||||
|
||||
describe('Middleware base tests', () => {
|
||||
describe('dev mode', () => {
|
||||
|
@ -110,7 +110,7 @@ describe('Middleware base tests', () => {
|
|||
})
|
||||
})
|
||||
|
||||
function urlTests(log, locale = '') {
|
||||
function urlTests(_log, locale = '') {
|
||||
it('rewrites by default to a target location', async () => {
|
||||
const res = await fetchViaHTTP(context.appPort, `${locale}/urls`)
|
||||
const html = await res.text()
|
||||
|
@ -146,18 +146,39 @@ function urlTests(log, locale = '') {
|
|||
})
|
||||
|
||||
it('warns when using Response.redirect with a relative URL', async () => {
|
||||
await fetchViaHTTP(context.appPort, `${locale}/urls/relative-redirect`)
|
||||
expect(log.output).toContain(urlsWarning)
|
||||
const response = await fetchViaHTTP(
|
||||
context.appPort,
|
||||
`${locale}/urls/relative-redirect`
|
||||
)
|
||||
expect(await response.json()).toEqual({
|
||||
error: {
|
||||
message: expect.stringContaining(urlsError),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('warns when using NextResponse.redirect with a relative URL', async () => {
|
||||
await fetchViaHTTP(context.appPort, `${locale}/urls/relative-next-redirect`)
|
||||
expect(log.output).toContain(urlsWarning)
|
||||
const response = await fetchViaHTTP(
|
||||
context.appPort,
|
||||
`${locale}/urls/relative-next-redirect`
|
||||
)
|
||||
expect(await response.json()).toEqual({
|
||||
error: {
|
||||
message: expect.stringContaining(urlsError),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('warns when using NextResponse.rewrite with a relative URL', async () => {
|
||||
await fetchViaHTTP(context.appPort, `${locale}/urls/relative-next-rewrite`)
|
||||
expect(log.output).toContain(urlsWarning)
|
||||
it('throws when using NextResponse.rewrite with a relative URL', async () => {
|
||||
const response = await fetchViaHTTP(
|
||||
context.appPort,
|
||||
`${locale}/urls/relative-next-rewrite`
|
||||
)
|
||||
expect(await response.json()).toEqual({
|
||||
error: {
|
||||
message: expect.stringContaining(urlsError),
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue