🖥️ NodeJS专栏:Node.js从入门到精通
🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述)
🖥️ TypeScript知识总结:TypeScript 学习笔记(十万字超详细知识点总结)
🧑💼 个人简介:大三学生,一个不甘平庸的平凡人🍬
👉 你的一键三连是我更新的最大动力❤️!
📑目录
🔽 前言
前面我们已经讲过
express
的路由和中间件,这一节我们将去介绍使用
express
时怎么获取请求的参数,以及客户端渲染和服务端渲染的区别与作用,让我们开始吧!
1️⃣ 获取请求参数
在讲解怎么获取请求参数之前,我们先定义好我们的
API
接口路由:
// apiRouter.jsconst express =require("express");// 使用路由级别中间件const router = express.Router();// 响应前端的get请求
router.get("/list",(req, res)=>{// 通过req.query获取URL地址上的参数(例如Get请求的参数)
console.log("参数为:", req.query);
res.send({ok: req.query });});// 响应前端的post请求
router.post("/list",(req, res)=>{// 通过req.body获取请求体中的参数(例如post/put请求的参数)
console.log("参数为:",req.body);
res.send({ok: req.body });});// 导出
module.exports = router;
- 通过
req.query
获取URL
地址上的参数 - 通过
req.body
获取请求体中的参数
之后在服务器上挂载我们的API路由:
// server.jsconst express =require("express");// 导入API路由文件const apiRouter =require("./route/apiRouter");const app =express();// 配置跨域
app.use((req, res, next)=>{// 设置允许任何源能访问服务器
res.header({"Access-Control-Allow-Origin":"*"});next();});// 挂载api路由
app.use(apiRouter);
app.listen(3000,()=>{
console.log("服务器启动!");});
启动服务器,然后我们创建一个
html
文件用来调用测试我们的
API
接口:
<!-- index.html --><body><buttonid="get">Get</button><buttonid="postF">Post:form编码参数</button><buttonid="postJ">Post:JSON参数</button><script>const get = document.getElementById('get')const postF = document.getElementById('postF')const postJ = document.getElementById('postJ')
get.onclick=()=>{}
postF.onclick=()=>{}
postJ.onclick=()=>{}</script></body>
🔹 获取URL地址上的参数
先测试一下
get
请求:
// index.html
get.onclick=()=>{fetch('http://localhost:3000/list?username=ailjx&age=18').then(res=> res.json()).then(res=>{
console.log(res);})}
可以看到我们服务端直接使用
req.query
就能获取URL地址上的参数,不需要做额外的处理。
调用 http://localhost:3000/list?a=1&b=2 时 req.query 为:{ a: ‘1’, b: ‘2’ }
🔹 获取请求体中的参数
先来试一下
form
编码格式的参数:
// index.html
postF.onclick=()=>{fetch('http://localhost:3000/list',{method:'POST',body:'username=ailjx&age=18',headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(res=> res.json()).then(res=>{
console.log(res);})}
form
编码格式对应的
Content-Type
为
application/x-www-form-urlencoded
,是
html
form
表单的默认提交方式,其参数格式与
URL
参数类似:
'username=ailjx&age=18'
可以看到服务端并不能直接通过
req.body
来获取请求体中的参数,想要获取请求体中
form
格式的参数需要我们配置以下中间件:
// server.js
app.use(express.urlencoded({extended:false}));// 或app.use(express.urlencoded({ extended: true }));
urlencoded
方法解析
form
编码格式的参数(
Content-Type: application/x-www-form-urlencoded
),如:
username=ailjx&age=18
urlencoded
中如果extended
设置为false
,那么对URL-encoded
的数据的解析采用querystring
库,解析结果为:[Object: null prototype] { username: 'ailjx', age: '18' }
urlencoded
中如果extended
设置为true
,那么采用qs
库,允许将富对象和数组编码为url
编码格式,允许使用url
编码的json
体验,解析结果为:{ username: 'ailjx', age: '18' }
上面两种解析结果都能直接通过
req.body.username
来访问参数中具体的字段。
在
post
这类请求中,往往传递的都是
JSON
格式的数据,那我们的服务端能直接获取
JSON
格式的数据吗?
// index.html
postJ.onclick=()=>{fetch('http://localhost:3000/list',{method:'POST',body:JSON.stringify({username:'ailjx',age:'18'}),headers:{'Content-Type':'application/json'}}).then(res=> res.json()).then(res=>{
console.log(res);})}
当我们点击按钮发送请求时报了这样的错误:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
译:预检前响应中的访问控制允许标头不允许请求标头字段内容类型。
这主要是因为我们前端发请求时修改了请求头的
'Content-Type'
为
'application/json'
,这个操作涉及到跨域被浏览器阻止了,我们只需要在服务端设置跨域时允许这个操作即可:
// server.js// 配置跨域
app.use((req, res, next)=>{// 设置允许任何源能访问服务器
res.header({"Access-Control-Allow-Origin":"*"});// 设置访问控制允许标头,允许自定义header的Content-Type字段
res.header({"Access-Control-Allow-Headers":"Content-Type"});// 新增next();});
之后再进行测试会发现虽然不报错了,但服务端依旧无法获取到参数,这时像处理
form
格式参数一样添加以下中间件即可:
// server.js// json方法解析json编码格式的post参数(Content-Type: application/json),如:{"username": "ailjx","age": "18"}
app.use(express.json());
注意: 可以同时配置
express.urlencoded
和
express.json
2️⃣ 应用渲染
🔹 客户端渲染
什么是客户端渲染?
客户端渲染(BSR) 又称 前端渲染,起源于
JavaScript
的兴起,
Ajax
网络请求技术的普及,真正意义上实现了前后端的分离,前端专注于
UI
,后端专注于逻辑。
前端通过
Ajax
请求获取服务端的数据,然后操作
DOM
将数据动态渲染到页面,渲染页面数据的过程发生在前端也就是客户端,所以称其为客户端渲染。
简单理解就是,客户端渲染就是前端组装页面
下面这个前后端分离的例子就是构建了一个客户端渲染的页面:
<body><divclass="main"><h1>前后端分离形式:客户端渲染(前端调用ajax请求后端数据再动态渲染到页面上)</h1><ulclass="list"></ul></div><script>// 发送Ajax请求向后端获取数据// http://localhost:3000/list返回的数据是[1, 2, 3, 4, 5, 6, 7, 8, 9]fetch('http://localhost:3000/list').then(res=> res.json()).then(res=>{render(res)})functionrender(data){let list = data.map(item=>`<li>${item}</li>`)
console.log(list);// 渲染数据到页面
document.querySelector('.list').innerHTML = list.join('')}</script></body>
打开页面并尝试在浏览器查看网页源代码:
可以看到我们动态渲染的数据在浏览器上查看源代码时是看不到的,这就是客户端渲染最大的问题:不利于SEO!
SEO,全称Search Engine Optimization,也即搜索引擎优化。
因为我们使用客户端渲染时,动态渲染到页面上的数据浏览器是看不到的,所以这些动态数据就不可能被网络爬虫爬取到,又因为像百度这类搜索引擎本质就是通过爬虫来爬取网页信息来实现的,所以客户端渲染就会对搜索引擎不太友好。
客户端渲染的优缺点都非常明显,优点:
- 完全的前后端分离。
- 数据渲染发生在客户端,能减轻服务端(服务器)的压力。
缺点:
- 不利于
SEO
。 - 请求量大时首屏渲染较慢(白屏问题)(因为前端需要时间去将数据绑定到页面上)。
🔹 服务端渲染
与客户端渲染对比来说,服务端渲染(SSR) 就很好理解了:
服务端渲染就是由后端(服务端)渲染数据,之后就直接将渲染数据后的页面发送给前端(客户端),前端只需进行展示即可。
简单理解就是,服务端渲染就是后端组装页面
后端渲染数据时常常是需要提前有一个页面模板的,当后端获取到需要展示的数据后,将数据填充到这个页面模板中,之后将填充过数据的模板页面给前端进行展示,这个模板称为模板引擎,下面是使用 **
ejs
模板引擎** 来演示服务端渲染的例子:
serverList.ejs
模板:
<!-- views/serverList.ejs --><body><divclass="main"><h1>使用模板引擎:服务端渲染(后端将数据与模板结合后再将结合过的页面返回给前端)</h1><ulclass="list"><!-- 下方代码的作用是:遍历展示数组数据 -->
<% data.forEach(function(item){ %>
<li>
<%-item %>
</li>
<% }); %>
</ul></div></body>
ejs
模板文件是以
.ejs
为后缀的文件,它完全兼容
.html
文件(就是能写任何
HTML
内容),并在此基础上添加了一些额外的ejs语法,如上面的
<%%>
中能写流程控制代码(
JS
代码),
<%- %>
中能写需要输出到模板的数据。关于
ejs
,博主之后会出单独的文章进行讲解,敬请期待!
server.js
服务器文件:
// server.jsconst express =require("express");const app =express();// 导入路由const Router =require("./route/router");// npm i ejs下载ejs// 配置模板引擎
app.set("views","./views");// 指定模板目录路径 (第一个参数views是固定写法)
app.set("view engine","ejs");// 指定模板后缀 (view engine是固定写法)// 挂载路由
app.use(Router);
app.listen(3000,()=>{
console.log("服务器启动成功!");});
route/router.js
路由文件:
// route/router.jsconst express =require("express");const router = express.Router();// 路由级别中间件// 服务端渲染页面
router.get("/serverList",(req, res)=>{// 使用render渲染serverList模板后返回给前端// res.send:能传递json数据和html页面// res.json:只能传递json数据// res.render:渲染模板// 第一个参数:找到views下的serverList.ejs// 第二个参数:需要传递给模板的数据
res.render("serverList",{data:[1,2,3,4,5,6,7,8,9]});});// 导出
module.exports = router;
启动服务器,打开
http://localhost:3000/serverList
查看效果:
可以看到这时我们动态渲染到页面的数据在浏览器检查源代码时就能检查的到了,这就是服务端渲染的最大好处:有利于SEO!
但服务端渲染的优缺点也很明显,优点:
- 有利于
SEO
。 - 首屏渲染速度快(因为数据绑定到页面的过程在服务端已经完成,前端渲染时相当于是直接渲染了个静态页面)。
缺点:
- 渲染数据过多时服务端的压力就会很大。
- 前后端不能完全分离。
🔹 怎样选择?
服务端渲染和客户端渲染的优缺点正好相反,但其实这两者并不是完全独立的,在一些应用开发中可能会同时使用服务端渲染和客户端渲染, 并不是说一个项目就只能是服务端渲染或客户端渲染,我们可以根据项目中不同页面的需求去自由选择/搭配这两种方式。
像
Vue
,
React
等前端框架(
SPA应用
)默认也都是客户端渲染,但它们都有支持服务端渲染的上层框架(
Nuxt.js
和
Next.js
)
🔼 结语
博主的Node.js从入门到精通专栏正在持续更新中,关注博主订阅专栏学习Node不迷路!
如果本篇文章对你有所帮助,还请客官一件四连!❤️
版权归原作者 海底烧烤店ai 所有, 如有侵权,请联系我们删除。