页面的两种生成方式
用户从浏览器地址栏中输入地址访问服务器上的页面时,服务器可以用两种不同的策略来生成这个页面。
打开给出的示意代码,观察效果。
(1)服务器端渲染Server Side Render
- 渲染是指:从数据到dom的过程(从json到html结构)
- 数据到dom的过程是发生在服务器端
- 客户端浏览器在地址栏中输入网页的地址,取回来的就是html页面。
(2)客户器端渲染 Client Side Render
- 渲染是指:数据到dom的过程 (从json到html结构)
- 数据到dom的过程是发生在客户端浏览器
- 客户端浏览器在地址栏中输入网页的地址,取回来的只是html骨架,
- 再去发ajax请求,取回来数据,再显示到页面上(用vue,arttemplate,模板字符串等技术)
小结
- ssr:服务器端渲染。数据组装(从json—>dom结果)的过程是发生在服务器上的。客户端取回来的是有数据页面。
- csr:客户端渲染。数据组装(从json—>dom结果)的过程是发生客户端(浏览器)的。主要是通过ajax取数据,再用模板技术(arttemplate,vue…)来渲染。
SEO与爬虫
客户端渲染技术对SEO不友好,爬虫无法获取有效内容!
什么是SEO
Search Engine Optimization ,搜索引擎优化。我们开发的网页肯定希望被更多人的知道,而推广自已的网页的方式之一是借助搜索引擎的力量,让其它人在百度中搜索某个关键字时就能找到你的网页。
那么,百度是如何得知http://xxxx.com/abc这个页面中有关键字javascript的呢?
百度服务器会使用一些程序来获取网页的内容,分析内容,以提取出关键字,便 于在搜索时能找到网页。 这个过程一般称为爬虫。
SEO的目标是更明确地告诉百度,你的网页上的内容,以便更好地被收录。
爬虫
我们平常上网都是在浏览器中请求网页地址,而爬虫代码是通过代码的方式去请求网页地址。
步骤:
-
创建一个.js文件(假设名字是spider.js)内容如下:
// 引入http模块 const http = require("http") // 定义要爬虫程序 访问的 网页 let url = "http://localhost:8080/index_csr.html" // let url = "http://localhost:8080/index_ssr.html" // 用http模块中的get方法去请求 url 这个网页,把请求到的结果 显示出来。 http.get(url, (res) => { let result = "" res.setEncoding('utf8'); res.on('data', (chunk) => { result += chunk }); res.on('end', () => { console.log(`爬虫得到的数据是: ${result}`); }); });
-
运行js文件
node spider.js
这一段代码会去请求代码中url指定的网页(可在这里下载运行示例代码),并打印出结果。 -
小结
对于采用客户端渲染的网页:爬虫程序无法获取有效的数据。(因为有效的数据是通过ajax在客户端发出来,去取回来的)
对于采用服务器端渲染的网页:爬虫程序可以获取有效的数据。(因为获取的内容就已经包含数据)
客户端渲染与服务器端渲染的区别
客户器渲染(通过ajax求数据)
优点 | 缺点 |
---|---|
适合前后端分离开发,方便维护,单页应用(SPA)中几乎都是客户端渲染 | 首屏加载慢,不利于 SEO |
服务器渲染
优点 | 缺点 |
---|---|
响应速度快,有利于 SEO | 前后端代码混合在一起,难以开发和维护,不适合进行前后端分离开发 |
我们使用vue开发的的项目都是典型的SPA(单页面应用程序single page application),是标准的前后端分离的,很显然是属于客户端渲染的范畴。
- 好处:页面导航不用刷新整个页面,体验好,有利于前后端分离开发
- 缺点:不利于 SEO(因为单页面应用中都是使用客户端渲染的方式),还有首次响应慢(第1次要加载大量的公共资源)
是否有相对折中的解决方案,或者是两全其美的解决方案呢?
Vue的SSR介绍及示例演示
Vue的SSR文档 : https://ssr.vuejs.org/zh/
Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
- 学习vue-server-renderer
- 在服务器端使用-server-renderer
创建项目( nodejs)
创建一个名为vuessr的空目录进入,并运行:
npm init --yes
来做初始化。
安装依赖
参考
npm install vue vue-server-renderer --save
示例:在node代码使用vue渲染数据
新建文件为01.js,内容如下:
const Vue = require('vue')
// 第 1 步:创建一个 vue实例
const app = new Vue({
template: `<div>{{title}}</div>`,
data:{
title:"hello,vue ssr!"
}
})
// 第 2 步:创建一个 renderer
const renderer = require('vue-server-renderer').createRenderer()
// 第 3 步:将 Vue 实例渲染为 HTML
// 方法一:回调函数
renderer.renderToString(app, (err, html) => {
if (err) throw err
console.log(html)
// => <div data-server-rendered="true">Hello World</div>
})
// 方法二:promise
// 在 2.5.0+,如果没有传入回调函数,则会返回 Promise:
renderer.renderToString(app).then(html => {
console.log(html)
}).catch(err => {
console.error(err)
})
运行结果:
node 01.js
输出结果如下:
<div data-server-rendered="true">hello,vue ssr!</div>
<div data-server-rendered="true">hello,vue ssr!</div>
小结:
vue-server-renderer就可以把Vue实例解析成 它对应的dom结构
示例:与服务器功能集成
目标:
请求网页http://localhost:3000/index.html,在服务器端使用vue-server-renderer来渲染生成html文档,并返回。
涉及npm包:
- express(安装express) npm i express
- vue, vue-server-renderer
创建02.js,代码如下:
/**
* 目标: 用户输入http://localhost:3000/index.html
* 在服务器使用vue-server-renderer来把vue实例渲染生成html文档,并返回
*
* 1) 先安装express
*/
const express = require('express')
const app = express()
const Vue = require('vue')
app.get('/index.html',(req, res) => {
// 1. 创建vue实例
const vm = new Vue({
template: `
<div>
<h2>{{title}}</title></h2>
<div v-for="item in list">
{{item.author}} - {{item.content}}
</div>
</div>
` ,
data: {
title: 'vue ssr',
list: [{author:"李白",content:"举杯邀明月"},
{author:"杜甫",content:"喝酒不开车"},
{author:"杜甫",content:"喝酒不开车"}]
}
})
// res.send('ok')
// 2. 创建一个renderer
const renderer = require('vue-server-renderer').createRenderer()
// 3. 渲染:把vue实例渲染成HTML字符串
renderer.renderToString(vm, (err, html) => {
if (err) {
console.log(err)
} else {
res.send(html)
}
})
})
app.listen(3000, ()=>{
console.log('3000.....')
})
运行
node 02.js
访问:
http://localhost:3000/index.html
- 小结:
在服务器使用vue,通过***vue-server-render***包,来把vue实例转成html字符串,再返回给客户端,这就是用vue技术的ssr。