概述
文章主要是抄的别人的,主要是作为记录。
先放大佬的文章地址:
怎么说呢,个人对于ssr有点执念。首先,我们知道ssr其实就是以前早期的mvc时代的M部分,也就是模板开发的那会。但是到了前后端分离的时代,ssr变成了一个较为复杂的东西。主要是因为现在的ssr因为react,vue等框架,是自带模板作用。如果直接在服务端使用是无法使用的。
然后我在去年的时候就自己反复的自建过ssr,像nuxt,eggjs自家提供的esaywebpack等都有尝试。但是自己经常会想,如果是公司最核心的项目需要用ssr,是应该自建还是用nuxt这样的框架。
而nuxt这样的框架有一个致命点,我们需要pm2这样的工具来保证多线程的性能使用。我在早先的时候使用eggjs,就不需要pm2。并且eggjs支持多线程启动,经历了双十一。所以我非常想把ssr和eggjs合并在一起。但是我还是想自己实现。
多次翻看官方ssr文档:https://ssr.vuejs.org/zh/,每次都是在webpack下面望而却步。主要是懒得,webpack搭建也不太熟。然后我就想能不能直接在vuecli3的基础上直接改造。
最终就抄来这片文章了。
流程
这块我不想概述了,主要就是抄的大佬的。上述作者的流程完整的走下来完全是可以的。
主要是两个坑点
1、关于koa-router部分的星号路由产生的报错
router.get("*", handleRequest);
我改为了了/
2、vue.config改造的时候启动的时候报错,
optimization这个是没有的,加上之后不会报错
optimization: {
splitChunks: TARGET_NODE ? false : undefined,
},
plugins: [TARGET_NODE ? new VueSSRServerPlugin() : new VueSSRClientPlugin()],
3、个人改造之后的git地址:https://github.com/ht-sauce/vue-cli3-ssr
如何验证自己改造成功呢?
看着大佬的改造成功跑起来之后呢自己其实有点方,不知道到底是否成功。
先讲一下关于百度等搜索引擎原理。其实核心原理就是一个爬虫程序会去请求你的地址,然后获取到你内部的html页面,最后根据html页面进行分析得到你的内容。
那spa为什么获取不到。给个例子:
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<link rel=icon href=/dve/favicon.ico>
<link rel=stylesheet type=text/css href=/dve/element-ui/2.13.0/index.css>
<script src=/dve/vue/2.6.11/vue.min.js></script>
<script src=/dve/element-ui/2.13.0/index.js></script>
<script src=/dve/vuex/3.0.1/vuex.js></script>
<script src=/dve/wavesurfer/wavesurfer.js></script>
<title>数字人视频编辑器</title>
<link href=/dve/css/digital.6f1b1310.css rel=prefetch>
<link href=/dve/js/digital.90f990ef.js rel=prefetch>
<link href=/dve/css/app.4434a726.css rel=preload as=style>
<link href=/dve/js/app.1936d768.js rel=preload as=script>
<link href=/dve/js/chunk-vendors.919914d8.js rel=preload as=script>
<link href=/dve/css/app.4434a726.css rel=stylesheet>
</head>
<body>
<noscript><strong>请允许浏览器执行JavaScript</strong></noscript>
<div id=app></div>
<script src=/dve/js/chunk-vendors.919914d8.js></script>
<script src=/dve/js/app.1936d768.js></script>
</body>
</html>
如上你在搜索引擎下得到的内容就是这样的。那能得到个锤子哦。
而搜索引擎要得到的内容是比如csdn这样的
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<link rel="canonical" href="https://blog.csdn.net/liumiaocn/article/details/108267949"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="renderer" content="webkit"/>
<meta name="force-rendering" content="webkit"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="report" content='{"pid": "blog", "spm":"1001.2101"}'>
<meta name="applicable-device" content="pc">
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta name="referrer" content="always">
<link rel="alternate" media="handheld" href="#" />
<meta name="shenma-site-verification" content="5a59773ab8077d4a62bf469ab966a63b_1497598848">
<meta name="csdn-baidu-search" content='{"autorun":true,"install":true,"keyword":"云IDE:Eclipse Che:Eclipse下一代IDE"}'>
<link href="https://csdnimg.cn/public/favicon.ico" rel="SHORTCUT ICON">
<title>云IDE:Eclipse Che:Eclipse下一代IDE_知行合一 止于至善-CSDN博客</title>
<meta name="keywords" content="云IDE:Eclipse Che:Eclipse下一代IDE">
<meta name="description" content="Eclipse Che被Eclipse官方称为下一代IDE,作为老牌的IDE,被其寄予厚望的Eclipse Che到底有什么特点,在这篇文章中我们来一探究竟。">
<script src='//g.csdnimg.cn/tingyun/1.8.3/blog.js' type='text/javascript'></script>
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/new_css/detail_enter-54d3fd4be5.min.css">
<script type="application/ld+json">{"@context":"https:\/\/ziyuan.baidu.com\/contexts\/cambrian.jsonld","@id":"https:\/\/blog.csdn.net\/liumiaocn\/article\/details\/108267949","appid":1638831770136827,"title":"\u4e91IDE\uff1aEclipse Che\uff1aEclipse\u4e0b\u4e00\u4ee3IDE_\u77e5\u884c\u5408\u4e00 \u6b62\u4e8e\u81f3\u5584-CSDN\u535a\u5ba2","pubDate":"2020-08-28T07:48:16","upDate":"2020-08-28T07:48:16"}</script>
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/themes_skin/skin-number/skin-number-01fe94d91c.min.css">
<!-- 自定义皮肤样式-->
<script src="https://csdnimg.cn/public/common/libs/jquery/jquery-1.9.1.min.js" type="text/javascript"></script>
<!--js引用-->
<script src="//g.csdnimg.cn/??fixed-sidebar/1.1.6/fixed-sidebar.js,report/1.5.6/report.js" type="text/javascript"></script>
<link rel="stylesheet" href="https://csdnimg.cn/public/sandalstrap/1.4/css/sandalstrap.min.css">
<style>
.MathJax, .MathJax_Message, .MathJax_Preview{
display: none
}
</style>
</head>
<body class="nodata " >
<link rel="stylesheet" href="https://csdnimg.cn/public/common/toolbar/content_toolbar_css/content_toolbar.css">
<script id="toolbar-tpl-scriptId" src="https://csdnimg.cn/public/common/toolbar/js/content_toolbar.js" type="text/javascript" domain="https://blog.csdn.net/"></script>
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/new_css/blog_code-c3a0c33d5c.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/vendor/pagination/paging-e040f0c7c8.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/new_css/chart-3456820cac.css" />
<div class="main_father clearfix d-flex justify-content-center" style="height:100%;">
<div class="container clearfix" id="mainBox">
<aside class="blog_container_aside">
<!--主页引入-->
<div id="asideProfile" class="aside-box">
<div class="profile-intro d-flex">
<div class="avatar-box d-flex justify-content-center flex-column">
<a href="https://blog.csdn.net/liumiaocn" data-report-click='{"mod":"popu_379","spm":"1001.2101.3001.4121","dest":"https://blog.csdn.net/liumiaocn","ab":"new"}'>
<img src="https://profile.csdnimg.cn/5/1/1/3_liumiaocn" class="avatar_pic" username='liumiaocn'>
</a>
</div>
<div class="user-info d-flex flex-column profile-intro-name-box">
<div>
<a href="https://blog.csdn.net/liumiaocn" class="" id="uid" title='淼叔' data-report-click='{"mod":"popu_379","spm":"1001.2101.3001.4122","dest":"https://blog.csdn.net/liumiaocn","ab":"new"}' >
<span class="name " username='liumiaocn'>
淼叔 </span>
</a>
<span></span>
<span class="flag expert-blog"><img class="identity" src="https://csdnimg.cn/identity/expert.png" alt=""><span class="bubble">CSDN认证博客专家</span></span>
<span class="flag company-blog"><span class="bubble">CSDN认证企业博客</span></span>
</div>
<div class="profile-intro-name-boxFooter">
<span class="personal-home-page">码龄4年</span>
<span class="personal-home-page"><a class="personal-home-certification" href="https://me.csdn.net/liumiaocn?utm_source=14998968" target="_blank"><img src="https://csdnimg.cn/identity/nocErtification.png" alt="">暂无认证</a></span>
</div>
</div>
</div>
大致是这个样子的,可以看到你的html内容里面是带有除了head头部之外的还有html标签等内容。
注意这是一次请求,不是你先像上面先请求页面路径,然后通过js再渲染页面的。记住,这是第一次请求的时候服务器给浏览器的内容
给个最简单的爬虫,自己试试
这个其实就很简单的,其实大家也可以用普通的ajax请求来试试。只要你请求到的内容是第一次就带有html标签等关键信息的,那么就是成功了。
下面是express部分的代码
安装其实就是
npm i express superagent cheerio
SuperAgent,用于服务端请求地址数据的
cheerio 就是一个最小jQuery,但是他可以在服务端使用
const express = require('express');
// 调用 express 实例,它是一个函数,不带参数调用时,会返回一个 express 实例,将这个变量赋予 app 变量。
const superagent = require('superagent');
const cheerio = require('cheerio');
const app = express();
app.get('/', (req, res, next) => {
superagent.get('http://localhost:3000')
.end((err, sres) => {
// 常规的错误处理
if (err) {
return next(err);
}
// sres.text 里面存储着网页的 html 内容,将它传给 cheerio.load 之后
// 就可以得到一个实现了 jquery 接口的变量,我们习惯性地将它命名为 `$`
// 剩下就都是 jquery 的内容了
let $ = cheerio.load(sres.text);
let items = sres.text;
console.log(sres.text)
/*$('.item_title a').each((idx, element) => {
let $element = $(element);
items.push({
title: $element.text(),
href: $element.attr('href')
});
});*/
res.send(items);
});
});
app.listen(5000, function () {
console.log('app is listening at port 5000');
});
最后
最后没啥,主要是表达下自己这次的文章比较潦草。
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 海天酱油_沃利贝尔 原文链接:https://juejin.im/post/6867348995866361870