express的使用(二) response的常用类型

news/2024/11/24 12:11:19/

文章链接:express的使用(二) response的常用类型,欢迎关注订阅号,提供更多技术文章

看前提示

在开发中,很多时候我们不需要写中间件,比较多的时候是做一个api接口,但是api接口的类型有很多,比如文章下载,重定向等,对我们开发而言,优先级比中间件还有cookie高,所以就先写一篇关于返回体的。
本文很多是照本宣科的,在官网很多时候会找到,只是整理下,就不一一粘贴原文的描述
本篇依旧是废话连篇,因为对很多新手来说,接触express的时候,都只是返回一个hello world。但是很多时候一个文本的hello world并不能满足我们的需求,所以才会有萌生水一篇关于response的想法,理所当然的,我也不会那么简单的列出几个api,而是从下面几个方向。去列出一些常用的api

依赖版本

    "pug": "^3.0.2","cookie-parser": "^1.4.6"

关于cookie

什么是cookie

HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储 cookie 并在下次向同一服务器再发起请求时携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器——如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。
Cookie 主要用于以下三个方面:

会话状态管理 如用户登录状态、购物车、游戏分数或其他需要记录的信息

个性化设置 如用户自定义设置、主题和其他设置

浏览器行为跟踪 如跟踪分析用户行为等

Cookie 曾一度用于客户端数据的存储,因当时并没有其他合适的存储办法而作为唯一的存储手段,但现在推荐使用现代存储 API。由于服务器指定
Cookie 后,浏览器的每次请求都会携带 Cookie 数据,会带来额外的性能开销(尤其是在移动环境下)。新的浏览器 API
已经允许开发者直接将数据存储到本地,如使用 Web storage API(localStorage 和 sessionStorage)或
IndexedDB 。

简单来说,cookie现在已经废了,但是不排除有的网站还在使用cookie存储一些数据,所以我们还是得看一下的,最主要,一些老开发还是会提及cookie的。总不能不知道人家在说什么吧0.0
关于cookie的domain以及path还有httpOnly这些,因为在这儿重要性不高,也就不多描述了,到时会专门找个时间记录下关于cookie的

res.cookie

  res.cookie("access_token", "Bearer 123", { httpOnly: true }).cookie("expire_time", "30000");

效果图如下,备注下,在f12打开的application页面中,点击cookie,然后选择我们的域名以及端口对应的cookie。就可以查看
在这里插入图片描述

res.clearCookie

根据键名,清除一个cookie,使用如下

  res.clearCookie("expire_time");

效果图,可见已经清除掉了第二个的expire_time了~
在这里插入图片描述

关于header

对于header的操作,在网站开发中比较少遇到,更多的是前端在header中传输token给我们,而后台又有在vary等字段的时候设置header的情况,但是堆nodejs而言,比较远(关于vary可以看下mdn的描述),故此,现在假设我们需要在header中添加一个token返回给前端。

res.append

往response的header中添加字段

router.get("/getUserDetail", function (req, res, next) {res.append("token", "12345");res.send();
});

效果图如下
在这里插入图片描述

res.locals

res.locals的使用情况比较简单,假设现在我们处理一个外部来的接口,不携带用户信息,只传来一个token,那么我们需要先在中间件中获取到用户的信息(鉴权),接着去根据用户的权限做出不同的操作,而从中间件传递到api的处理的过程,如果为了request的纯净,我们就可以将res中设置一个变量在locals中,而设置在locals中的变量,并不会传递到前端中去,而在node端,却可以安心的使用它。

router.get("/getUserDetail", function (req, res, next) {res.locals.user={name:"mk",sex:1};console.log(res.locals.user.name);res.send();
});

效果图如下
在这里插入图片描述
在这里插入图片描述

关于json格式的

这是我们最常用的方式,一个api接口,我们需要返回数据,很多时候是json格式的数据,但也因为它的普遍性,所以没有什么需要说明的,只要知道用法就可以了~

res.json

router.get("/getUserDetail", function (req, res, next) {res.json({ fail: false, message: "return by res.json" });
});

res.send

router.get("/getUserDetail", function (req, res, next) {res.send({ fail: false, message: "return by res.send" });
});

两者返回的body没有区别,但是需要注意下content-type,res.send会标注出返回的content-type是application/json.虽然默认都是application/json…

在这里插入图片描述

备注下,res.send(“<h1>title</h1>”);也是可以发送html到前端的,只是这样子的话,response中的Content-type就会变成text/html;

关于重定向

重定向,必须是重点,毕竟每次我们登录后,都要跳转到首页,或则是重定向到过来的页面,而这时候就必须要用到重定向了。

res.redirect

router.get("/getUserDetail", function (req, res, next) {res.redirect("/blog/getBlogDetail");//res.redirect是可以跳转到外部的网站
//  res.redirect("https://www.baidu.com");
});

res.location

router.get("/getUserDetail", function (req, res, next) {res.location("/blog/getBlogDetail");
});

很遗憾,对于有些同学,想要再重定向之后,将登录的token放在req的header中带过去,但是说过了,req的更多的是只读的(这儿就不贴代码了)
再github上关于这种操作的,比如在redirec中想要更改header的,建议看下这边issues
https://github.com/expressjs/express/issues/3551

但是呢,还是可以有个骚操作,能称得上骚操作,当然只是权宜之计

router.get("/getUserDetail", function (req, res, next) {res.cookie("token","aaaaaaaa");res.redirect("/blog/getBlogDetail");
});
router.get("/getBlogDetail", function (req, res, next) {res.header("content-type", "application/json");console.log(req.cookies["token"]);res.end("博客模块的getBlogDetail");
});

思路就是由于redirect的时候是完结一个请求,从浏览器的角度就是从A接口收到304,然后马上访问b接口,由于是在同一个服务,而根据cookie的特性,就可以将参数设置在A接口的cookie中,从b接口拿到之后,从cookie中删除,但是!cookie本身是http请求的一部分,所以数据量多的时候,会让http请求变得很大,并且可能cookie会被我们的中间件拦截,属于不正规的,有很大风险的方式,所以称之为骚操作
但是现在测试下,而我们需要在server.js中使用cookie-parser来读取cookie。

const cookieParser = require("cookie-parser");
app.use(cookieParser());

关于返回一个html页面

上一篇在路由中,只是简单的设置了一个api,让它能走通,并没有设置到500页面以及404页面,而关于404页面,很多时候需要用到,而为了代码的整洁性,不能将404页面的整个html变成字符串返回过去,所以就需要用到下面的函数(其实渲染的概念不怎么需要解释,想必各位在学习vue,react等都有过渲染的理解,就不多描述了)
个人比较喜欢用pug,就用pug做个简单的例子

server.js中注册pug

app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");

在server.js的同级目录创建一个views的文件夹,然后在其中放置一个index.pug的文件,代码如下:

doctype html
html(lang="en")headtitle= pageTitlescript(type='text/javascript').if (foo) bar(1 + 5)bodyh1 Pug - node template engine#container.colif youAreUsingPugp You are amazingelsep Get on it!p.Pug is a terse and simple templating language with astrong focus on performance and powerful features.

在代码中render这个文件

 res.render("index", { name: "name" });

即可在浏览器中访问到页面,如何获取参数,pug的官网有一堆资料,我就不在此扩展了,基本动动手指就能找到

需要注意下, render函数是渲染模板引擎,如果是要返回一个html文件,建议用res.sendFile
文件在刚刚描述的views文件夹中创建

router.get("/getUserDetail", function (req, res, next) {res.sendFile(path.join(__dirname, "./../../views/a.html"));
});

关于下载文件

下载文件的绝对不是冷门,也绝对不是最简单的,毕竟文档中关于这些的就有很多,比如刚刚提及到来的sendFile,以及接下来要描述的attachment还有download

res.attachment

Sets the HTTP response Content-Disposition header field to “attachment”. If a filename is given, then it sets the Content-Type based on the extension name via res.type(), and sets the Content-Disposition “filename=” parameter.

router.get("/getUserDetail", function (req, res, next) {res.attachment(path.join(__dirname, "./../../views/a.html"));res.send();
});

没啥好说的,部分同学会忘记res.send。以及需要注意该方式会修改’Content-Disposition’即可~

res.downlaod

res.downlaod绝对是我比较喜欢的下载的方式,很简单,因为有监听函数!!!

router.get("/getUserDetail", function (req, res, next) {res.download(path.join(__dirname, "./../../views/a.html"),(err)=>{console.log(err);console.log("下载完成!");});
});

当然,Content-Disposition也会被修改~,且支持4.16.x以上,但是现在都4.18.x了,我想就不用多说了

参考文档

https://www.expressjs.com.cn/4x/api.html


http://www.ppmy.cn/news/75205.html

相关文章

从8连挂到面面offer,我只用了一个月,面试25K测试岗血泪经验分享给你

直到如今&#xff0c;我才敢把这段经历分享出来&#xff0c;毕竟一个多月前&#xff0c;我是经历了面试八连挂的人。作为一只骄傲的软件测试工程师&#xff0c;恨不得找一块豆腐撞死。但是在闭关修炼了一个多月之后&#xff0c;重新出来面试&#xff0c;面试了五家公司&#xf…

jvm之G1 GC

写在前面 jdk9以及之后的版本已经将默认的垃圾收集器parallel更换为G1.本文就一起来看下。 1&#xff1a;G1介绍 parallel GC的设计目标是高吞吐量&#xff0c;CMS GC的设计目标是低延迟&#xff0c;而G1的设计目标不是这二者中的任何一个&#xff0c;其设计目标是让GC的STW…

用数据讲故事:十大统计学/机器学习魔法指数

统计学和机器学习为数据分析提供理论基础&#xff0c;入门时我看过很多统计学相关书籍&#xff0c;复杂的公式和推导过程让我一度陷入迷茫。对于数据科学/分析师来说&#xff0c;如何使用统计学知识并应用到我们的分析场景中更为重要。本文主要基于数据分析工作中的实际应用场景…

rust cargo工具常用插件列表

插件功能安装命令advisory检查 Cargo 依赖项中是否存在安全漏洞。cargo install cargo-advisoryasm生成 Rust 代码的汇编版本。cargo install cargo-asmaudit搜索 Rust 代码及其依赖项中的安全漏洞并输出警告。cargo install cargo-auditbenchcmp比较 Rust 基准测试结果。cargo…

(1分钟速览)g2o入门指南--笔记版

在slam后端中&#xff0c;优化的框架很多&#xff0c;有ceres&#xff0c;g2o&#xff0c;gtsam这些。要想真正掌握slam后端的优化内容&#xff0c;这些框架是必不可少的上手练习的内容。本文则介绍有关g2o的相关内容&#xff0c;作为一个入门指南&#xff0c;目标&#xff1a;…

【重新定义matlab强大系列七】利用matlab函数ischange查找数据变化点

&#x1f517; 运行环境&#xff1a;matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

可视区域兼容性问题的思考及方法封装

今日在复习可视化尺寸获取时突发奇想&#xff0c;为什么要在怪异模式下使用document.body.clientWidth&#xff0c;在标准模式下使用document.documentElement.clientWidth&#xff1f;以及是否在IE8及以下的版本中其中一个获取方式将返回undefined或0。  出于该问题的思考&am…

Java字节流battle字符流

目录 Java字节流&#xff08;Byte Stream&#xff09; FileInputStream和FileOutputStream Java字符流&#xff08;Character Stream&#xff09; FileReader和FileWriter 如何在使用是区分什么时候用输出什么时候用输入 Write方法 close方法 Java中的close方法本身抛出…