天天看點

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

來源:慕課網

本文原創釋出于慕課網 ,轉載請注明出處,謝謝合作