传参:
静态文件处理:
get方式拿数据:req.query
post方式拿数据:通过body-parser这个中间件解析,然后req.body得到数据
安装方式: npm i body-parser -D (这个中间件不能解析上传的文件)
添加接口之前就应该添加中间件,然后中间件里相当于有了个next()
使用原生的post拿数据模拟body-parser:
封装出去,做成自己的body-parser:
在post传递数据的时候,如何做到随来随切数据?(简单了解)
自动机:
简单来说会涉及到一个定界符&,post数据的特点是一个字符一个字符的读,什么时候读到&了,什么时候就说明之前读到的东西就 已经能够作为一个单元来解析了。一个字一个字的读,如果现在这个包读完了,都没有读到&,那就说明这个包不能自己独立存在,他还涉及到后面的数据,那么就再接着等,这个包就先留着,然后什么时候读到了,从开始的那个点到我现在这个点整个切走作为一个数据扔出去,然后接下来再期盼着下一个&。
上传文件的中间件:multer:他只能上传文件,不能传普通的post,通常和body-parser混着用
安装:npm i multer -D
上传文件信息输出如下:
拓展:线程和进程
线程:
1)性能高
同一个进程之内的线程之间是共享内存,共享计数器。所以开销要小。
2)安全性低
线程是个逻辑上的产物,因为不是独立的,如果一个线程出错了,整个进程全死。所以安全性弱一些。
java是多线程语言(也是混合的)
进程:
1)性能低
进程与进程之间是独立的,是不能共享数据的,如果想共享数据,比如管道,比如共享内存区, 每个进程有自己的独立的内存,独立的计数器。这是为什么多进程性能低,因为在切进程的时候,他需要把整个内存中的东西全部都要换了,这个切换的成本非常高,把栈全部清空了,然后重新装填,并且把计数器给清零然后重新开始。切换往往是以毫秒为单位,对于计算机来说毫秒为单位的操作是非常慢的。
2)安全性高
因为是相互独立的,一个进程死了,只要死的不是主进程,其他的问题不大。
nodeJS、php、python是多进程语言
JS和nodeJS如何创建进程?
JS:
new Worker();
NodeJS:
cluster.fork(); fork完了之后直接一分为二,一个变成主进程,一个变为子进程,再fork n次,就会创建n个子进程。
主进程从来不干活,都会把任务丢给子进程去做,因为如果主进程死了,子进程就都全完了。这样也保护了程序的安全,
多进程,多线程之外,还有另一种编程流派:一种是基于事件的。如C语言中的epoll,比如说nodeJS中的回调,回调也是一种事件,所以这就是在多进程多线程之外又开辟了一种新的方式,这种也不错,既利于编程简单,同时又能发挥性能,因为一般情况下,绝大多数应用都是CPU密集型的任务。真正用的时候都是为了保护主进程的安全。一般我们又有启动器,所以也用不着他保护,这就很矛盾。好吧....
在express中,其实最重要的是对各种中间件的使用。
cookie:
存储在浏览器,在请求服务器的时候,会顺便发送给服务器,往往用他来作为一种用户凭证。
问题:不安全
因为cookie是存在浏览器,造假怎么办,因为cookie是能改的,任何存储在浏览器中的数据都是不安全的,因为用户那边可以随时篡改。
session:
特性:存储在服务器,不是独立的,基于cookie。浏览器请求的时候传一个id,服务器会根据这个id去给到数据。
问题:安全问题
session劫持:如果有个用户A特别蠢,前提是服务器也很蠢,对sessionID没有做加密,另一个用户B去A用户的机器上把他的sessionID复制走了,在B的电脑上填进去了,那么服务器就会认为B是A。
token就是存储在cookie中的sessionID
在服务端如何存储cookie?
cookie-parser中间件
安装:npm i cookie-parser -D
cookie是不跨域的,只能在当前的域名下去访问这个域名的cookie,不能去访问别的域名的cookie,比如在百度去访问淘宝的cookie。
cookie中的子域名可以访问父域名的cookie,但是父域名不能访问子域名的cookie。
一般整个网站是一套cookie的,不可能每个频道都单独整个cookie,否则就乱了。
domain:一般domain设置的是主域名,这就告诉了这个cookie是以主域名的身份在保存,不要存到子域名里面去,否则访问不到(因为主不能去访问子的cookie)。
path:一般情况下,path直接设置为根目录 ‘/’。因为他可以往上访问,但是不能往下访问。比如根目录和根目录下的user,在user中是可以访问根目录 / 的东西的,但是在根目录/ 是不能去访问user中的东西的。
签名cookie提高安全性:
签过名的cookie在浏览器中看到:
解析value:
解读:s冒号标志着我这个cookie是个签名cookie,s.值.签名,当服务器接到这个值的时候,他不会直接去信任这个值,服务器会利用这个签名密钥再重新对服务器接到的这个值去重新做次签名,然后跟这个签名密钥去做比对,对的上就认,对不上就不认,
如果用户在浏览器中把前面的值99.8改成了9999.8然后回车,服务器那边会输出:
代表签名没通过, 并且会把原来浏览器的value恢复成原样。
除非有一种情况,我改这个值的时候,我也改签名,重新签名才能让服务器认这个cookie。但是对于普通用户来说,他是不知道这个签名的,所以自然就无法对这个签名做出正确的操作。所以也就达到了保护cookie的作用。
所以核心保护cookie就是保护那段自己设置的签名密钥。
session一般并不能独立存在,因为服务器取调取这个session也必须通过一个标志,你得告诉我你是谁,然后我才能调取你相应的数据,那么这个时候呢,咱们就需要一个id,用户那边需要一个ID(有人叫sessionID,有人叫token)叫什么无所谓,但性质就是一个ID的性质,来表明我是谁,所以session一定不是独立存在的,百分之九十的情况下,是配着cookie用的。还可以跟localstroge,跟微信配着用,比如说有些应用他是通过微信来登录的,然后通过微信登录呢他就在微信那边得到一个openID,还会得到sessionKey,然后利用这个找服务器要东西,这也是一种可能,所以说不一定非要存在cookie,也可以通过其他的来做第三方认证,但是无论如何,得有一个东西给你一个ID你才能用。
cookie-session中间件:
安装:npm i cookie-session -D
这个模块有个特点:是天然强势加密的,不加密不行,用"我"就得加密
运行上面程序,访问localhost:8080/a,在cookie中可以看到
不断刷新网页就会记录到第n次来到访本站
session的value就是sessionID,别人就可以把这个sessionID复制走,冒充是你,但是因为有下面那个session.sig来保护他,他不能随便去篡改这个东西,如果把sessionID改了,他是不认的,就会把cookie给清空了。他就会认为你是第一次来,刷新cookie,就会还会有原来的那个cookie
因此,我们可以把一些机密的信息存入到session中,这样在浏览器中能显示出来,但是在cookie中是看不到的,cookie中只是存的这条数据对应的id。
session是存在服务器上的,那么具体存在服务器的哪?
-- 绝大部分session是存在文件里的,但是呢老是操作文件会很慢,需要从文件里面读,然后写到文件,读写读写很慢,所以有些人可以把session保存到数据库中,也可以保存在redis里,或者存在内存里面都可以。
现在的(上面的或者说不指定)的session存在了电脑上的temp文件中:
比如存在mysql里:express-mysql-session
安装: npm i express-mysql-session -D
session能存在localstroge或者sessionstroge里面吗?
-- 不行,因为session的优势是不保存在客户端,而存在服务端,如果仍在本地存储里,这个优势就消失了啊。
express没法支持大型的项目开发。