V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
wenfengand
V2EX  ›  问与答

静态文件方法解决 Vue SEO 的尝试

  •  
  •   wenfengand · 2019-04-03 20:17:09 +08:00 · 474 次点击
    这是一个创建于 2057 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    最近在做一个 Baas + Element UI + Vue 的动态博客,原型是Codebear的作品,不同之处是他的后端采用了 Mysql + php。我修改了一下前端代码,使其支持 Baas。修改完后终于要解决一个重大的问题:SEO。

    Vue 或者单页面应用的好处是用户体验好,与服务器交换的数据少;弊端是搜索引擎无法收录内容页。Vue SEO 也有很多解决方案,如 Vue SSR,PreRender 等等。简单看了下,这些方案大多需要服务器运行特定程序,如 nodejs,判断 User Agent 选择服务端渲染或者前端渲染。这些文档看得我头疼,实在是太复杂且不适合我的应用场景。

    应用场景:博客网站,文章内容页需要 SEO, 后台管理不需要,但 Codebear 的博客系统内容页和管理页统一用 vue。之前采用 hexo 生成静态文件,放到腾讯云 COS 的方式,已经有数百个静态页面。

    方案

    想了一种新的解决方案(在搜索引擎中没找到),并进行了初步尝试。

    方案描述:前端在渲染完成后,获取整个 html 文档( DOM 树),并传输到静态文件托管服务器,放到 url 所指定的路径下。由于只是一次简单的尝试,没有写 JS 代码,使用 Chrome 浏览器的调试功能,在 Element 选项卡中的 html tag 处右键选择 Edit as HTML,之后全选复制粘贴到一个 html 文档中。如下图所示。 图片 在腾讯云 COS 管理平台新建文件夹 try_seo_vue, 将 html 文档重命名为 index.html 放到这个文件夹下。并把该文档所需的静态文件( js、css、image )也放到指定路径。

    在新浏览器页面中访问这个链接, 能够看到之前保存的静态页面。部分链接点不开,因为使用了动态的 router.push.

    问题

    这种方案也可能会存在其他问题:

    JS 能否获取渲染之后的 html 文档, 或者 vue 有没有函数是可以直接输出渲染后的字符串? 前端发送的页面是否可信,是否会被篡改 内容页的动态内容无法加载,如最近文章、相关文章、评论、阅读量等等 html 文档体积较大,大概是因为 dev 模式?

    不知道这种方式有没有什么问题?还望各位大佬不吝赐教,如果没问题就开始干了。

    noe132
        1
    noe132  
       2019-04-03 21:57:29 +08:00 via Android   ❤️ 1
    如果项目前后端分离,不包括服务端渲染的,可以较小成本迁移到 nuxt.js 。迁移好后配置一下需要生成静态文件的动态路由,可以直接 generate 静态文件,并且前后端同构,浏览器首次加载无需重新渲染。并且 nuxt 自带了 vue-meta,也可以方便管理页面 meta 信息
    每次有文章更新,可以手动重新 generate,或者配置 hook 或者 ci 自动构建。

    至于评论,我建议可以不需要预渲染,只预渲染文章内容就可以了,让用户用浏览器打开页面时再动态加载评论。这样不需要每次有人评论就得重新渲染页面,也能保持页面一致性。
    wenfengand
        2
    wenfengand  
    OP
       2019-04-03 23:46:10 +08:00
    @noe132 看样子已经有更好的实现工具了,感谢,我去学习下 nuxt.js
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5434 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 100ms · UTC 01:25 · PVG 09:25 · LAX 17:25 · JFK 20:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.