Node.js「四」—— 路由 / EJS 模板引擎 / GET 和 POST

本文为 Node.js 系列笔记第四篇。文章参考:nodejs 教程;《深入浅出 Node.js》;阮一峰 nodejs 博客Node.js v16.13.0 文档

一、路由


路由(Routing)是由一个 URL (路径)和一个特定 HTTP 方法(GET、POST 等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。

简单来说,路由指的就是针对不同请求的 URL,处理不同的业务逻辑。如下图所示:
在这里插入图片描述

  • 示例
    // 路由
    let myURL = new URL(req.url, 'http://127.0.0.1:3000/');
    let pathname = myURL.pathname;

    if (pathname == '/login') {
        res.writeHead(200, { 'Content-Type': 'text/html; charset="utf-8"' });
        res.end("登录");
    } else if (pathname == '/register') {
        res.writeHead(200, { 'Content-Type': 'text/html; charset="utf-8"' });
        res.end("注册");
    } else if (pathname == '/admin') {
        res.writeHead(200, { 'Content-Type': 'text/html; charset="utf-8"' });
        res.end("后端业务逻辑");
    } else {
        res.writeHead(404, { 'Content-Type': 'text/html; charset="utf-8"' });
    }
    res.end();

 

二、EJS 模板引擎


什么是模板引擎?

模板引擎让表现层 (HTML 文档) 和业务数据分离。 通过特定的语法,来动态地用数据渲染出 HTML 文档。

在这里插入图片描述

HTML 文档在服务器用模板引擎根据数据动态地渲染好,然后直接将渲染完整的页面响应给客户端。浏览器加载完页面内容可以立即展示,增加了用户体验,同时也有利于 SEO 优化。

 
什么是 EJS 模板引擎?

EJS 是一套简单的模板语言,帮你利用普通的 JavaScript 代码生成 HTML 页面。可以让你在不破坏 HTML 文档结构的情况下,直接在标签内书写 JavaScript 代码。

 
怎么使用 EJS?

它是一个第三方模块,需要通过 npm 安装 —— npm ejs 。具体使用可参考 EJS 官方网站

具体用法有下面几种:

	let template = ejs.compile(str, options);
	template(data);
	// => 输出渲染后的 HTML 字符串
	
	ejs.render(str, data, options);
	// => 输出渲染后的 HTML 字符串
	
	ejs.renderFile(filename, data, options, function(err, str){
	    // str => 输出渲染后的 HTML 字符串
	});

 
EJS 有什么语法?

其实 EJS 的语法和 HTML 差不多,只要最后文件后缀名改成 .ejs,它就成为了 EJS 模板文件。

在模板中,<% %> 括起来的内容会作为 Javascript 代码来编译;<%= %><%- %>将括起来的变量中的数据渲染到模板。(还有一些其他的标签,后文再进行说明)

比如,下面的模板会将 list 数组中的 title 属性值用 for 循环一个个地渲染到 <li> 元素中。

    <%for(var i=0; i < list.length; i++){%>
    	<li>
        	<%=list[i].title%>		// 绑定数组 list 中数据 title 
    	</li>
    <%}%>

 

举个例子说明一下

利用 ejs.renderFile 方法可以将服务器中获取的数据 data 渲染到前台。

http.createServer(function (req, res) {
    // 创建静态 WEB 服务器
    routes.static(req, res, 'static');

    // 路由 
    let myURL = new URL(req.url, 'http://127.0.0.1:3000/');
    let pathname = myURL.pathname;

    if (pathname == '/login') {
        let msg = '数据库里面获取的数据';			// 假装这就是数据库里获取的数据

        ejs.renderFile('./views/login.ejs', { msg: msg }, (err, data) => {
            res.writeHead(200, { 'Content-Type': 'text/html; charset="utf-8"' });
            res.end(data);
        })
    }
}).listen(3000);

上述代码中,{ msg: msg } 就将数据 msg 渲染到了前台,也就是 ./views/login.ejs 中。那么,前台页面如何将后台渲染的数据进行绑定呢?这就用到了 ejs 特有的标签,如 <%= 等(后文介绍)。

下面来看前台页面 login.ejs

	<!DOCTYPE html>
	...
	<body>
	    <h3>
	        ejs模板引擎
	    </h3>
	    <p>
	        <%=msg%>
	    </p>
	</body>
	
	</html>

这样,我们就可以看到后台数据已经被渲染到了前台页面。
在这里插入图片描述
同时,我们也可以看到其 HTML 结构也发生了改变。
在这里插入图片描述
这就是动态数据,当数据库中的数据发生改变时,页面信息也会对应改变。
 

下面来看 EJS 中的特有标签

  1. <%:脚本标签,用于流程控制(里面可以写循环语句或条件语句),无输出。比如,你可以在里面放一个 for 循环来渲染多个数据。
  2. <%_:删除其前面的空格符
  3. <%=:输出数据到模板(输出是转义 HTML 标签)
  4. <%-:输出非转义的数据到模板
  5. <%#:注释标签,不执行、不输出内容
  6. <%%:输出字符串 ‘<%’
  7. %>:一般结束标签
  8. -%>:删除紧随其后的换行符
  9. _%>:将结束标签后面的空格符删除

 
再来个例子感受一下

	let msg = "数据库里面所获取的数据";
    let list = [
        {
            title: '关注'
        },
        {
            title: '推荐'
        },
        {
            title: '热榜'
        },
        {
            title: '吾辈问答'
        },
    ]
    // 动态加载
    ejs.renderFile('./views/login.ejs', {
        msg: msg,
        list: list
    }, (err, data) => {
        res.writeHead(200, { 'Content-Type': 'text/html; charset="utf-8"' });
        res.end(data);
    });

login.ejs 文件

	<!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.0">
	    <title>Document</title>
	</head>
	
	<body>
	    <h3>
	        <%=msg%>
	    </h3>
	    <ul>
	        <%for(var i=0; i < list.length; i++){%>
	            <li>
	                <%=list[i].title%>
	            </li>
	        <%}%>
	    </ul>
	</body>
	
	</html>

实现效果
在这里插入图片描述
 

三、GET 和 POST


1. 概述

Http 定义了与服务器交互的不同方法,最基本的方法有 4 种,分别是 GETPOSTPUTDELETE
 
URL 全称是资源描述符,我们可以这样认为:一个 URL 地址,它用于描述一个网络上的资源,而 HTTP 中的 GETPOSTPUTDELETE 就对应着对这个资源的 4 个操作。到这里,大家应该有个大概的了解了,GET 一般用于获取/查询资源信息,而 POST 一般用于更新资源信息。

超文本传输协议 HTTP 设计目的是保证客户端机器与服务器之间的通信。在客户端和服务器之间进行请求-响应时,两种最常用到的方法就是 GETPOST

  1. GET:从指定的资源请求数据。一般用于获取数据。
  2. POST:向指定的资源提交要被处理的数据。一般用于提交数据。
  • GET

GET 请求的数据会附在 URL 中,如下图:
在这里插入图片描述

  • POST

POST 请求通常是通过 HTML 表单发送,并返回服务器的修改结果。

    <form action="/doLogin" method="post">
    ...
    </form>

POST 通过 request body 传递参数,如下图:
在这里插入图片描述
在这里插入图片描述

  • 示例

下面是一个利用 POST 提交表单数据的例子。通过 ejs 来渲染

请添加图片描述

服务器 app.js

http.createServer(function (req, res) {
    routes.static(req, res, 'static');

    // 路由
    let myURL = new URL(req.url, 'http://127.0.0.1:3000/');
    let pathname = myURL.pathname;

    if (pathname == '/login') {
        // 使用 ejs 渲染
        ejs.renderFile("./views/form.ejs", {}, (err, data) => {
            res.writeHead(200, { 'Content-Type': 'text/html; charset="utf-8"' });
            res.end(data);
        })
    } else if (pathname == '/doLogin') {
        // 获取 POST 传值
        let postData = '';
        // 拿到数据片段进行拼接
        req.on('data', (chunk) => {
            postData += chunk;
        })
        // 传输结束触发
        req.on('end', () => {
            console.log(postData);
            res.end();
        })
    } else {
        res.writeHead(404, { 'Content-Type': 'text/html; charset="utf-8"' });
    }
}).listen(3000);

form.ejs

<!DOCTYPE html>
...
<body>
    <form action="/doLogin" method="post">		// 指定为 POST 请求
        用户名:<input type="text" name="username">
        密 码:<input type="password" name="password">
        <input type="submit" value="提交">
    </form>
</body>
...

 

2. GET 和 POST 区别


参见 W3C 说明:w3school: GET 对比 POST
在这里插入图片描述
 

3. 其他常见问题


声明:以下内容抄录其他文章

GET 和 POST 报文上的区别 ?

先下结论,GET 和 POST 方法没有实质区别,只是报文格式不同

GET 和 POST 只是 HTTP 协议中两种请求方式,而 HTTP 协议是基于 TCP/IP 的应用层协议,无论 GET 还是 POST,用的都是同一个传输层协议,所以在传输上,没有区别。

  1. 报文格式上,不带参数时,最大区别就是第一行方法名不同:

    POST 方法请求报文第一行是这样的 POST /uri HTTP/1.1 \r\n
    GET 方法请求报文第一行是这样的 GET /uri HTTP/1.1 \r\n

  2. 带参数时。在约定中,GET 方法的参数应该放在 url 中,POST 方法参数应该放在 body 中。

问题 1:POST 方法比 GET 方法安全?

按照网上大部分文章的解释,POST 比 GET 安全,因为数据在地址栏上不可见。

然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。

要想安全传输,就只有加密,也就是 HTTPS。

问题 2:GET 方法的长度限制是怎么回事?

在网上看到很多关于两者区别的文章都有这一条,提到浏览器地址栏输入的参数是有限的。

首先说明一点,HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因。

浏览器原因就不说了,服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

imByte

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值