一、问题描述
环境:Node 18.14.0,Nuxt 3.12.2 with Nitro 2.9.6
后台粉丝提问,能否在Nuxt3的页面中不要生成__NUXT_DATA__,因为里面包含了接口返回的数据,感觉数据暴露并且加大了页面的html内容的大小:
<script type="application/json" id="__NUXT_DATA__" data-ssr="true">
...
</script>
二、解决方案
其实在之前的文章《Nuxt3:探索useFetch是如何做到避免客户端重复请求》提到了__NUXT_DATA__
与Nuxt payload有关,所以是不建议将这个机制破坏的,在《How do I remove NUXT data in script tags from html pages in Nuxt.js 3?》一文的讨论中也提到不应该将它删除。
但如果既想要SSR,也真想删了它有没有办法呢?这里想到了一个办法可以尝试一下,那就是在服务端渲染出html的时候,对其进行修改。
这里就要提到Nuxt的生命周期钩子:服务器钩子,一起看一下:
这里简单做个试验:
通过打印,可以发现__NUXT_DATA__的节点代码就在html.bodyAppend
数组中,所以先直接将其设置为空数组:
运行结果如下:
可以看到页面上没有再出现__NUXT_DATA__
节点,但报了一些js错误,同时在Network中也没有发现重复请求数据接口:
为了解决上述报错,直接对html.bodyAppend
做一点修改:
// server/plugins/modifyHtml.js
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (html, { event }) => {
// html.bodyAppend.push('<hr>由自定义插件追加的内容')
html.bodyAppend = ['<script>window.__NUXT__={};window.__NUXT__.config={public:{BASE_URL:"/",BASE_API_URL:"https://xxxx.com"},app:{baseURL:"/",buildId:"dev",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script>']
})
nitroApp.hooks.hook('render:response', (response, { event }) => {
// console.log('render:response', response)
})
})
运行结果没有报错,但会有一个新的问题,就是Network会重新请求数据接口:
但对于SEO来说,爬虫访问页面肯定是能拿到完整的html了,只是在客户端浏览器显示时,会有一种一闪而过的感觉(因为客户端会重新发送请求更新视图)。
以上只是在开发环境下的一种试验,如果真有这种需求,可能还需要进一步完善代码,在生产环境中要多验证,避免产生副作用。