Fix image optimization encoding url (#28045)
- Fixes #27973 - Reverts #27671 The problem with PR #27671 is that it was encoding too often when it really only needed to solve the bug for `next build && next start` since `next dev` was already working. This PR uses the alternative solution mentioned here https://github.com/vercel/next.js/issues/27210#issuecomment-890305204
This commit is contained in:
parent
1552b8341e
commit
b11bd49239
7 changed files with 145 additions and 6 deletions
|
@ -69,22 +69,20 @@ export async function imageOptimizer(
|
|||
}
|
||||
|
||||
const { headers } = req
|
||||
const { url: decodedUrl, w, q } = parsedUrl.query
|
||||
const { url, w, q } = parsedUrl.query
|
||||
const mimeType = getSupportedMimeType(MODERN_TYPES, headers.accept)
|
||||
let href: string
|
||||
|
||||
if (!decodedUrl) {
|
||||
if (!url) {
|
||||
res.statusCode = 400
|
||||
res.end('"url" parameter is required')
|
||||
return { finished: true }
|
||||
} else if (Array.isArray(decodedUrl)) {
|
||||
} else if (Array.isArray(url)) {
|
||||
res.statusCode = 400
|
||||
res.end('"url" parameter cannot be an array')
|
||||
return { finished: true }
|
||||
}
|
||||
|
||||
const url = encodeURI(decodedUrl)
|
||||
|
||||
let isAbsolute: boolean
|
||||
|
||||
if (url.startsWith('/')) {
|
||||
|
|
|
@ -1158,7 +1158,14 @@ export default class Server {
|
|||
pathParts.splice(0, basePathParts.length)
|
||||
}
|
||||
|
||||
const path = `/${pathParts.join('/')}`
|
||||
let path = `/${pathParts.join('/')}`
|
||||
|
||||
if (!publicFiles.has(path)) {
|
||||
// In `next-dev-server.ts`, we ensure encoded paths match
|
||||
// decoded paths on the filesystem. So we need do the
|
||||
// opposite here: make sure decoded paths match encoded.
|
||||
path = encodeURI(path)
|
||||
}
|
||||
|
||||
if (publicFiles.has(path)) {
|
||||
await this.serveStatic(
|
||||
|
|
5
test/integration/image-component/unicode/next.config.js
Normal file
5
test/integration/image-component/unicode/next.config.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
images: {
|
||||
domains: ['image-optimization-test.vercel.app'],
|
||||
},
|
||||
}
|
33
test/integration/image-component/unicode/pages/index.js
Normal file
33
test/integration/image-component/unicode/pages/index.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
import img from '../public/äöü.png'
|
||||
|
||||
const Page = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Unicode Image URL</h1>
|
||||
<Image id="static" src={img} />
|
||||
<Image id="internal" src="/äöü.png" width={400} height={400} />
|
||||
<Image
|
||||
id="external"
|
||||
src="https://image-optimization-test.vercel.app/äöü.png"
|
||||
width={400}
|
||||
height={400}
|
||||
/>
|
||||
<Image
|
||||
id="internal-space"
|
||||
src="/hello%20world.jpg"
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
<Image
|
||||
id="external-space"
|
||||
src="https://image-optimization-test.vercel.app/hello%20world.jpg"
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page
|
BIN
test/integration/image-component/unicode/public/hello world.jpg
Normal file
BIN
test/integration/image-component/unicode/public/hello world.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
test/integration/image-component/unicode/public/äöü.png
Normal file
BIN
test/integration/image-component/unicode/public/äöü.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
96
test/integration/image-component/unicode/test/index.test.js
Normal file
96
test/integration/image-component/unicode/test/index.test.js
Normal file
|
@ -0,0 +1,96 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
import {
|
||||
findPort,
|
||||
killApp,
|
||||
launchApp,
|
||||
nextBuild,
|
||||
nextStart,
|
||||
} from 'next-test-utils'
|
||||
import webdriver from 'next-webdriver'
|
||||
//import fetch from 'node-fetch'
|
||||
import { join } from 'path'
|
||||
|
||||
jest.setTimeout(1000 * 60)
|
||||
|
||||
const appDir = join(__dirname, '../')
|
||||
|
||||
let appPort
|
||||
let app
|
||||
let browser
|
||||
|
||||
function runTests() {
|
||||
it('should load static unicode image', async () => {
|
||||
const src = await browser.elementById('static').getAttribute('src')
|
||||
expect(src).toMatch(
|
||||
/_next%2Fstatic%2Fimage%2Fpublic%2F%C3%A4%C3%B6%C3%BC(.+)png/
|
||||
)
|
||||
const res = await fetch(src)
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
it('should load internal unicode image', async () => {
|
||||
const src = await browser.elementById('internal').getAttribute('src')
|
||||
expect(src).toMatch('/_next/image?url=%2F%C3%A4%C3%B6%C3%BC.png')
|
||||
const res = await fetch(src)
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
it('should load external unicode image', async () => {
|
||||
const src = await browser.elementById('external').getAttribute('src')
|
||||
expect(src).toMatch(
|
||||
'/_next/image?url=https%3A%2F%2Fimage-optimization-test.vercel.app%2F%C3%A4%C3%B6%C3%BC.png'
|
||||
)
|
||||
const res = await fetch(src)
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
it('should load internal image with space', async () => {
|
||||
const src = await browser.elementById('internal-space').getAttribute('src')
|
||||
expect(src).toMatch('/_next/image?url=%2Fhello%2520world.jpg')
|
||||
const res = await fetch(src)
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
it('should load external image with space', async () => {
|
||||
const src = await browser.elementById('external-space').getAttribute('src')
|
||||
expect(src).toMatch(
|
||||
'/_next/image?url=https%3A%2F%2Fimage-optimization-test.vercel.app%2Fhello%2520world.jpg'
|
||||
)
|
||||
const res = await fetch(src)
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
}
|
||||
|
||||
describe('Image Component Unicode Image URL', () => {
|
||||
describe('dev mode', () => {
|
||||
beforeAll(async () => {
|
||||
appPort = await findPort()
|
||||
app = await launchApp(appDir, appPort)
|
||||
browser = await webdriver(appPort, '/')
|
||||
})
|
||||
afterAll(() => {
|
||||
killApp(app)
|
||||
if (browser) {
|
||||
browser.close()
|
||||
}
|
||||
})
|
||||
runTests()
|
||||
})
|
||||
|
||||
describe('server mode', () => {
|
||||
beforeAll(async () => {
|
||||
await nextBuild(appDir)
|
||||
appPort = await findPort()
|
||||
app = await nextStart(appDir, appPort)
|
||||
browser = await webdriver(appPort, '/')
|
||||
})
|
||||
afterAll(() => {
|
||||
killApp(app)
|
||||
if (browser) {
|
||||
browser.close()
|
||||
}
|
||||
})
|
||||
runTests()
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue