当前位置:   article > 正文

Nuxt3踩坑日记 - window.__NUXT___nuxt3 windows

nuxt3 windows

在这里插入图片描述

会将整个页面获取到的数据全部储存起来,在一个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)
        }
    });
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
// nuxt.config.ts
export default defineNuxtConfig({
	nitro: {
    compressPublicAssets: true,
    plugins: [
      '~/mixin/nitro-hooks.ts',
    ]
  },
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

结果:并没有什么卵用,这个方法在用户每次请求都会生成一个文件,不合理。(错误实例


第二次尝试

对一次尝试进行优化,思路: 预先生成版本号(时间戳 大于 当前时间),每次生成文件时,判断是否有该版本号的文件,
有: 直接读取
无: 生成文件

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>`;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

需要注意的是,需要把 nuxt.config.ts 改个配置

export default defineNuxtConfig({
	// .......
	experimental: {
		// 不把数据生成一个单独的 JSON
	    renderJsonPayloads: false
	  },
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结果
在这里插入图片描述
这里文件已经写入,也成功引用了,但是却有了副作用,控制台报错
在这里插入图片描述
在这里插入图片描述
写入的文件并没有识别到。

待解决:
1、需要一个静态资源文件夹,将写入的内容写到静态文件夹
2、版本号的时间戳小于当前时间戳,需重新刷新版本号


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/971326
推荐阅读
相关标签
  

闽ICP备14008679号