赞
踩
会将整个页面获取到的数据全部储存起来,在一个id="NUXT_DATA"的 script 标签里。查阅官方文档,github讨论区,发现众多网友都有此问题,但官方大大并不认为这有问题。
这就需要你页面的数据全部脱敏才行,不然真的明目张胆的将数据完全暴露出去。
问题无解,暂未找到很合理的办法。
使用render:html钩子在加载页面前提取__NUXT_DATA__数据放到一个新的 js 文件存到_nuxt下, 再插入新的 script 来外部引用,能够减少页面大小
// 文件目录 /mixin/nitro-hooks.ts // 使用 nitro-hooks import fs from 'fs'; import path from 'path'; export default defineNitroPlugin((nitro) => { nitro.hooks.hook("render:html",async (html, events) => { const data = html.bodyAppend[0]; const regex = /<script type="application\/json" id="__NUXT_DATA__" data-ssr="true">([^<]*)<\/script>/; // 要写入的内容 const content = data.match(regex)[1]; // ========= const routePath: any = events.event.context.matchedRoute // scriptSrc const buildAssetsDir = events.event.context.nitro.runtimeConfig.app.buildAssetsDir; // 例如,向打包后的文件写入一个文件 // 确保目标文件的目录存在,如果不存在则创建 const distDir = '/_nuxt/' if (!fs.existsSync(distDir)) { fs.mkdirSync(distDir, { recursive: true }) } const fileName = `state-${routePath.params._ || "home" }.js` // 构建完整的文件路径 const filePath = path.join(distDir, buildAssetsDir, fileName); // 使用 fs 模块向文件中写入内容 try { const scriptSrc = path.join(buildAssetsDir, fileName); await fs.promises.appendFile(filePath, content); html.bodyAppend[0] = data.replace(regex, `<script defer src="${scriptSrc}"></script>`); console.log('Custom content has been written to the file:', filePath) } catch (error) { console.error('Error writing content to file:', error) } }); })
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
compressPublicAssets: true,
plugins: [
'~/mixin/nitro-hooks.ts',
]
},
})
结果:并没有什么卵用,这个方法在用户每次请求都会生成一个文件,不合理。(错误实例
对一次尝试进行优化,思路: 预先生成版本号(时间戳 大于 当前时间),每次生成文件时,判断是否有该版本号的文件,
有: 直接读取
无: 生成文件
export default defineNitroPlugin((nitroApp) => { nitroApp.hooks.hook("render:html",async (html, { event }) => { // 当前路由 => 首页 const route = event._path.replaceAll("/", "__"); // 版本号 const version = (new Date("2024-06-30").getTime()).toString(); // 匹配到需要提取的 __NUXT_DATA const nuxtData = getNuxtDataContent(html.bodyAppend[0]); // 获取当前工作目录 const currentDirectory = process.cwd(); const _nuxtDirectory = path.join(currentDirectory, 'public', '_nuxt'); // 版本文件夹 const versionDirectory = path.join(_nuxtDirectory, `state-${route}-${version}.js`); console.log(`版本文件: ${versionDirectory}`); // 是否存在 if (!fs.existsSync(versionDirectory)) { try { console.log("不存在 => 创建"); // 不存在 => 创建 await fs.mkdirSync(_nuxtDirectory, { recursive: true });0 await fs.promises.writeFile(versionDirectory, nuxtData, 'utf-8'); html.bodyAppend[0] = replaceContent(html.bodyAppend[0], version, route); console.log('Custom content has been written to the file:', versionDirectory); } catch (error) { console.error('Error writing content to file:', error) } } else { console.log("存在 => 直接替换"); // 存在 => 直接替换 html.bodyAppend[0] = replaceContent(html.bodyAppend[0], version, route); } }) }) // 提取 __NUXT_DATA__ value function getNuxtDataContent (data) { const regex = /<script>([^<]*)<\/script>/; const content = data.match(regex)[1]; return content; } // 字符替换 返回值 function replaceContent (data, version, route) { // const regex = /<script type="application\/json" id="__NUXT_DATA__" data-ssr="true">([^<]*)<\/script>/; // const content = data.replace(regex, `<script type="application\/json" id="__NUXT_DATA__" data-ssr="true" defer src="/_nuxt/state-${route}-${version}.js"></script>`); // return content; return `<script defer src="/_nuxt/state-${route}-${version}.js"></script>`; }
需要注意的是,需要把 nuxt.config.ts 改个配置
export default defineNuxtConfig({
// .......
experimental: {
// 不把数据生成一个单独的 JSON
renderJsonPayloads: false
},
})
结果
这里文件已经写入,也成功引用了,但是却有了副作用,控制台报错
写入的文件并没有识别到。
待解决:
1、需要一个静态资源文件夹,将写入的内容写到静态文件夹
2、版本号的时间戳小于当前时间戳,需重新刷新版本号
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。