天天看点

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)

前言

我们都知道,

Vue

React

是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出自定义组件,进行生成

DOM

和操作

DOM

, 也就是我们常说的客户端渲染, 并且我们大部分主流的场景都是

SPA

(单页面)应用, 而随着

SPA

尤其是

React

Vue

Angular

为代表的前端框架的流行,越来越多的

Web App

使用的是客户端渲染。

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)

使用

客户端渲染

的优势在于

节省后端资源

局部刷新

前后端分离

等,但随着应用的日益复杂,

首屏渲染时间

不断变长, 并且存在严重的

SEO

问题。

所以为了解决

SPA

应用遇到的这些问题, 我们必须考虑

SSR

:

服务端渲染(ssr) ,是指由服务器端完成页面的 HTML 结构拼接,并且直接将拼接好的 HTML 发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的处理技术。

对于服务端渲染的页面,服务端可以直接将带数据的内容通过 HTML 文本的形式返回,

搜索引擎爬虫

可以轻易的获取页面内容,而对于客户端渲染的应用,客户端必须执行服务器返回的

Javascript

才能得到正确的网页内容。目前,除

Google

Bing

支持

Javascript

外(也会有一些限制),其他的大部分搜索引擎都不支持

Javascript

,也就无法获取正确的网页内容。而本文要讲的技术方案,正是为了解决

SPA

下的

SSR

技术困境.接下来我们看看常用的ssr技术实现方案.

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)

摘要

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)

ssr(服务端渲染)技术实现方案

接下来笔者将列举几个常用的基于

vue

/

react

的服务端渲染方案,如下:

  • 使用next.js/nuxt.js的服务端渲染方案
  • 使用node+vue-server-renderer实现vue项目的服务端渲染
  • 使用node+React renderToStaticMarkup实现react项目的服务端渲染
  • 传统网站通过模板引擎来实现ssr(比如ejs, jade, pug等)
  • 使用rendertron实现SPA项目的服务端渲染

以上是笔者之前实践过的方案, 最后一种方案笔者将在下面一节详细介绍, 因为

next

/

nuxt

是已有的服务端渲染解决方案,文档写的比较详细,这里笔者就不再做过多介绍了,这里我们简单介绍一下第二种和第三种方案.

1.使用node+vue-server-renderer实现vue项目的服务端渲染

首先vue-server-renderer依赖node的api,所以只能运行在node环境, 我们需要先安装它:

npm install vue vue-server-renderer --save
           

在node中使用,代码如下:

const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()

server.get('*', (req, res) => {
  const app = new Vue({
    data: {
      url: req.url
    },
    template: `<div>趣谈前端: {{ url }}</div>`
  })

  renderer.renderToString(app, (err, html) => {
    if (err) {
      res.status(500).end('Internal Server Error')
      return
    }
    res.end(`
      <!DOCTYPE html>
      <html >
        <head><title>Hello</title></head>
        <body>${html}</body>
      </html>
    `)
  })
})

server.listen(8080)
           

当然实际情况比上面的案例要复杂很多, 我们可以专门写一个template.html,然后通过模板差值的方式导入后端数据,进而实现服务端渲染. 在使用这种方式的时候我们仍然要维护两套代码.

2.使用node+React renderToStaticMarkup实现react项目的服务端渲染

使用这种方案和vue的方案类似, 只不过这里我们用了react自带的api来实现ssr,简单的实现代码如下:

var express = require('express');
var app = express();
 
var React = require('react'),
    ReactDOMServer = require('react-dom/server');
 
var App = React.createFactory(require('./App'));
 
app.get('/', function(req, res) {
    var html = ReactDOMServer.renderToStaticMarkup(
        React.DOM.body(
            null,
            React.DOM.div({id: 'root',
                dangerouslySetInnerHTML: {
                    __html: ReactDOMServer.renderToStaticMarkup(App())
                }
            })
        )
    );
 
    res.end(html);
});
 
app.listen(80, function() {
    console.log('running on port ' + 80);
});
           

以上使用了

renderToStaticMarkup

, 我们都知道react-dom提供了两种服务端渲染函数,如下:

  1. renderToString :将 React Component 转化为 HTML 字符串,生成的 HTML 的 DOM 会带有额外属性:各个 DOM 会有data-react-id属性,第一个 DOM 会有data-checksum属性。
  2. renderToStaticMarkup :将 React Component 转化为 HTML 字符串,但是生成 HTML 的 DOM 不会有额外属性,从而节省 HTML 字符串的大小。

所以这里我们一般使用

renderToStaticMarkup

函数. 同理在实际业务场景中我们也会写2套代码来实现

ssr

.

使用谷歌rendertron实现服务端渲染

Google

推出的

Rendertron

使得

SPA

也能够被不支持执行

Javascript

的搜索引擎爬取渲染后的内容。其原理主要是通过使用

Headless Chrome

在内存中执行

Javascript

,并在得到完整内容后,将内容返回给客户端。

我们通常会将

Rendertron

部署为一个独立的

HTTP

服务,然后为

Web

应用框架配置

Google

官方提供的中间件或者在反向代理上添加相应路由规则,使得能够在检测到搜索引擎爬虫的

UA

时,可以将请求代理给

Rendertron

服务。笔者总结了一下其基实现本原理图,方便大家理解:

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)
Rendertron

提供了两个主要 API:

  • Render 用于渲染网站内容
  • Screenshot 用于将网站内容截图

在 SEO 场景下我们使用的是

Render

接口。

比如当客户端请求我们的网站时,我们服务端可以根据请求头

User Agent

发现是否包含了

Baiduspider/2.0

关键字,如果是, 那么可以认定为当前的客户端是一个百度爬虫此时可以将这个请求代理 Rendertron 服务的

/render/客户端请求地址

路由,让

Rendertron

帮助执行网页内的

Javascript

,并将最终内容返回给搜索引擎爬虫。

使用

Rendertron

的好处在于我们可以不用考虑服务端渲染的部分,完全按照

SPA

的模式开发项目,也不用为了兼容服务端渲染而写多余的兼容代码.

具体实现

首先我们需要安装Rendertron, 可以在

github

中找到其安装和使用方法,在安装前最好先安装

docker

, 目前

docker

的最新版本以支持傻瓜式安装,所以安装启动都非常方便.

1.本地运行

在安装好docker之后, 我们先全局安装rendertron:

npm install -g rendertron
           

然后我们需要安装谷歌浏览器(作为合格的开发都应该有谷歌浏览器~),然后就可以用它的cli来启动服务了,我们只需要在命令行执行如下命令:

rendertron
           

之后控制台会打印本地服务启动的地址,比如

localhost:3000

这个时候我们只需要在地址后面输入我们想渲染的网站即可:

localhost:3000:render/你的网站地址

,

如下图所示:

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)

此时我们的

rendertron

服务已经搭建完成, 接下来我们可以在服务端来实现ssr了,代码如下:

const koa = require('koa');
const app = new koa();
app.use(async (ctx, next) => {
    ctx.type = "html";
    if(/Baiduspider/2.0/g.ctx.header['user-agent']) {
      // 是百度爬虫,则转发到rendertron服务中
      ctx.redirect(`http://localhost:3000/render/${ctx.url}`)
    }else {
        // 渲染正常的路由页面
    }

    await next();
    })

app.listen('80');
           

当然如果我们后端技术栈采用的是

express

, rendertron有专门的中间件可以使用, 不仅仅可以拦截百度的爬虫,具体用法如下:

const express = require('express');
const rendertron = require('rendertron-middleware');

const app = express();

app.use(rendertron.makeMiddleware({
  proxyUrl: 'http://your-rendertron-instance/render',
}));

// 正常的路由和页面渲染逻辑
app.use(...);
app.listen(81);
           

所以为了降低开发成本笔者建议可以采用

rendertron

的方案, 单独部署一套服务器用来实现

ssr

. 但是我们需要考虑当网站流量增加时的扩容问题,以及配置搭建反向代理或负载均衡等配套服务。

后期展望

后期笔者将会继续带大家探索大前端相关内容, 基本框架如下:

js通过url获取网页渲染的html_快速在你的vue/react应用中实现ssr(服务端渲染)

最后

如果想学习更多

H5游戏

,

webpack

node

gulp

css3

javascript

nodeJS

canvas数据可视化

等前端知识和实战,欢迎在《趣谈前端》加入我们的技术群一起学习讨论,共同探索前端的边界。

作者:徐小夕

链接:http://www.imooc.com/article/details/id/310593

来源:慕课网

本文原创发布于慕课网 ,转载请注明出处,谢谢合作