Nuxt3踩坑日记 - window.__NUXT__

在这里插入图片描述

会将整个页面获取到的数据全部储存起来,在一个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、版本号的时间戳小于当前时间戳,需重新刷新版本号


  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值