fix: encoding issues with payload paths (#8738)

- fix(generator): decode full static filesystem paths
- fix(vue-app): check decoded path against manifest
- fix(vue-app): prevent double encoding for urls

Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
Daniel Roe 2021-02-02 12:38:54 +00:00 committed by GitHub
parent f917297a70
commit 6a8339e4c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 7 deletions

View File

@ -343,7 +343,7 @@ export default class Generator {
// Save Static Assets
if (this.staticAssetsDir && renderContext.staticAssets) {
for (const asset of renderContext.staticAssets) {
const assetPath = path.join(this.staticAssetsDir, asset.path)
const assetPath = path.join(this.staticAssetsDir, decodeURI(asset.path))
await fsExtra.ensureDir(path.dirname(assetPath))
await fsExtra.writeFile(assetPath, asset.src, 'utf-8')
}

View File

@ -1,5 +1,5 @@
import Vue from 'vue'
import { parsePath, withoutTrailingSlash } from 'ufo'
import { parsePath, withoutTrailingSlash, normalizeURL } from 'ufo'
<% utilsImports = [
...(features.asyncData || features.fetch) ? [
'getMatchedComponentsInstances',
@ -317,7 +317,7 @@ export default {
},
<% if (nuxtOptions.generate.manifest) { %>
async fetchStaticManifest() {
return window.__NUXT_IMPORT__('manifest.js', encodeURI(urlJoin(this.getStaticAssetsPath(), 'manifest.js')))
return window.__NUXT_IMPORT__('manifest.js', normalizeURL(urlJoin(this.getStaticAssetsPath(), 'manifest.js')))
},
<% } %>
setPagePayload(payload) {
@ -328,14 +328,14 @@ export default {
<% if (nuxtOptions.generate.manifest) { %>
const manifest = await this.fetchStaticManifest()
const path = this.getRoutePath(route)
if (!manifest.routes.includes(path)) {
if (!manifest.routes.includes(decodeURI(path))) {
if (!prefetch) { this.setPagePayload(false) }
throw new Error(`Route ${path} is not pre-rendered`)
}
<% } %>
const src = urlJoin(this.getStaticAssetsPath(route), 'payload.js')
try {
const payload = await window.__NUXT_IMPORT__(decodeURI(route), encodeURI(src))
const payload = await window.__NUXT_IMPORT__(decodeURI(route), normalizeURL(src))
if (!prefetch) { this.setPagePayload(payload) }
return payload
} catch (err) {

View File

@ -1,7 +1,8 @@
import http from 'http'
import { resolve } from 'path'
import { join, resolve } from 'path'
import serveStatic from 'serve-static'
import finalhandler from 'finalhandler'
import glob from 'glob'
import { Builder, Generator, getPort, loadFixture, Nuxt, rp } from '../utils'
let port
@ -43,7 +44,21 @@ describe('full-static', () => {
const { body: html } = await rp(url('/payload'))
expect(html).toContain('<script src="https://cdn.nuxtjs.org/test/')
expect(html).toContain('<link rel="preload" href="https://cdn.nuxtjs.org/test/_nuxt/static/')
expect(html).toContain(
'<link rel="preload" href="https://cdn.nuxtjs.org/test/_nuxt/static/'
)
})
test('/encoding/中文', async () => {
const { body: html } = await rp(url('/encoding/中文'))
const paths = ['encoding/中文/state.js', 'encoding/中文/payload.js']
paths.forEach((path) => {
const files = glob.sync(join(distDir, '**', path))
expect(html).toContain(encodeURI(path))
expect(files).toContainEqual(expect.stringContaining(path))
})
})
// Close server and ask nuxt to stop listening to file changes

View File

@ -7,6 +7,9 @@
<NLink to="/store">
Store
</NLink>
<NLink to="/encoding/中文">
Encoding
</NLink>
<NLink to="/pagination/1">
Pagination
</NLink>

View File

@ -0,0 +1,5 @@
<template>
<div>
<h1>Encoded path</h1>
</div>
</template>