前言
看视频结合做demo,断断续续学了一个月Node.js,在这里贴一下我的Node.js学习笔记,就作为一个学习Node.js的整理和归纳吧
简介
为什么学Node.js?
- 学Node.js就是学Web服务器开发。从招聘上来讲,具有服务端开发经验会更好
Node.js是什么?
- 它是
javascript
的运行环境,可以解释并执行js代码。一般来说js需要在浏览器的帮助下才能运行,而Node.js可以让js单独运行 - 它既不是语言也不是库也不是框架
- 它使用V8引擎,可以解析js代码,是一个JS虚拟机(Node.js的作者把V8引擎移植出来开发了独立的js运行环境)
- 不适合从来没有接触过服务端的人学习(因为比较偏底层,很灵活)
Node.js包含什么?
- Ecmascript(不像浏览器那样还包含了DOM和BOM)
- 在Node.js这个js环境中为js提供了一些服务器操作级别的API,例如文件读写、网络服务器构建、网络通信(所以主要是做服务端这些事),还可以读写、生成文件,而浏览器不可以做到
Node.js特性:
- 事件驱动
- 非阻塞IO模型(简单来说是异步操作)
- 轻量和高效
Node.js能做什么?
- web服务器后台:像PHP、Java
- 开发命令行工具:像C开发git、Node开发npm、hexo(对于前端开发工程师来讲,接触Node最多的是命令行工具,但是我们自己却写的很少,大部分都是使用别人写的:webpack,gulp,npm)
通过这门课学到了什么?
- B/S编程模型(浏览器和服务器模型/browser-server/back-end 任何服务端技术这种BS编程模型都是一样的,和语言无关,即模型和概念是一样的)
- Node.js只是作为我们学习BS编程模型的工具
- 模块化编程
- require.js
- sea.js
- @import
- Node.js常用API
- 异步编程
- 回调函数(在Node.js里面有很多回调函数的使用)
- promise
- async
- generator
- express ——web开发框架
- ES6
- 帮大家打开服务器的黑盒子,还可以帮助学习前端高级内容:vue、react、angular 等有很大帮助
特点:
- 高度的自由化,可以选择要安装的功能(安装第三方包)
- 灵活,高度DIY,可以通过代码指定哪些文件能通过目录访问哪些文件不可以(指定公共和私有文件)
起步
- 下载、安装
- 新建一个js文件,里面写一些内容
- 按住
shift
+右键
可以打开命令行窗口 - 用
cd
定位到当前目录 node
+文件名
运行文件- 运行成功,这个时候js已经是脱离浏览器运行了
如何通过一个url地址访问html?
- 在用Apache时都是通过把html放置在指定文件目录里然后设置默认打开页面
- 而现在用Node,我们要做的就是像创建Apache功能那样(因为默认并没有Apache那样的封装能力)
学习
读取文件
- buffer是二进制数据流,文件中存储的是二进制数据,我们直接读取文件默认是看到二进制转十六进制的结果,可以通过
toString
转为可以看懂的字符串 - 那么什么时候需要转化为字符串呢?——当你需要对字符串进行操作的时候,才有必要使用
toString()
简单的http服务
- Node可以非常轻松简单地构建web服务器,在Node中专门提供了一个核心模块:http ,http这个模块的职责就是帮忙创建服务器的
- 服务器设置
- 服务器启动
Ctrl
+c
关闭服务器- 所有的请求都是以
/
开头 - 如果代码修改了服务器一定要重启才能生效(后面会有方便重启的工具:
nodemon
) - res.write()其实比较麻烦,一般很少用,推荐直接res.end(‘hello world’)的同时发送响应数据。注意响应内容只能是二进制或者字符串,其他的不行(数字、对象、数组、布尔值)
- 简写:自动把这个函数作为它request事件的函数。
http.createServer
的返回值是server
,所以也可以直接
:http.createSever().listen('8080',function(err){})
http.createServer(function(req,res){
//...
})
.listen('8080',function(err){
//...
})
URL模块(核心模块)(旧接口被废弃)
- url:统一资源定位符->最终是定位到一个资源
- 模块中有个parse(url,true)方法,可以把url转换为对象,在返回的对象里面可以快捷的通过
query
获取key&value,通过pathname
获取不包含query的路径(通过开启true
,才能使query转为对象),用处就是用来判定请求路径,而排除其他干扰(比如key&value) - 出现 **[Object: null prototype]**问题:旧url接口已经被废弃:解决办法
return:
- 阻止代码继续执行
- 方法返回值
Node需求:
- Apache软件有个www目录,所有存放在www的都可以通过url地址来访问到
- 模仿Apache:使得Node能通过url来直接访问目录下的任意资源(通过拼接url来实现),且在访问目录时可以显示目录列表(类似于浏览器访问本地文件夹那样的效果)
- Apache那种文件列表的基础功能,其实是它软件本身已经帮你实现。本身后面自带了代码进行处理
- 获取目录下的全部文件名:
fs.readdir
- 将获取到的文件名信息替换到html中的指定位置:模板引擎(字符串解析替换):
fs.readFile
读取文件并获取html- 用
data.toString
转换成字符串 - 用
data.replace('@@@','替换的字符串')
来替换事先写的占位符
- 但是以上步骤不方便且麻烦,于是我们要用模板引擎来方便解决替换占位符问题
- 获取目录下的全部文件名:
express:
- 高度封装了http模块。是第三方web开发框架。目的是提高编程效率,更专注于业务而不是底层细节
知识点
重定向
了解:
- 客户端发出请求后,服务器接收到请求时可以对客户端请求的页面重定向,改变请求的页面路径
如何重定向
- 设置状态码为302(临时重定向):
res.statusCode = 302
(还有301的永久重定向) - 响应头中通过location告诉客户端往哪里重定向:
res.setHeader('location','/')
客户端收到服务器的响应状态码是302后,就会自动去响应头找location,然后对该地址发出新的请求
永久重定向和临时重定向的区别:
- 302:客户端访问a.com,接收到状态码为302时都会去响应头找location,对地址b.com发出新请求。之后访问流程相同
- 301:客户端第一次访问a.com,接收到状态码为302时都会去响应头找location,对地址b.com发出新请求,之后再访问a.com时不会再去对a.com发出请求,而是直接请求b.com
表达提交
了解:
- 表单中要提交的必须有name属性
- 表单提交分为:
- 默认的提交行为:不用写代码,默认发送
- 异步提交:需要自己写代码提交请求
- action是表单的请求地址
- mothod:请求方法
URL请求
请求:
- 页面本身就是一个get的url请求,并且页面里的每一个资源也是请求。当请求后收到html文件时,浏览器会从上到下进行解析,若发现了
link
、script
、img
、iframe
、video
、audio
等具有src或者href属性的时候,浏览器会自动对这些静态资源发起新的请求,而它们里面所写的请求路径就是url。url就是字符串,它其实和实际文件中文件所存放的位置并没有关系,它可以是任何字符串,然后只要服务端事先约定好这些字符串请求即可 - 可以判断页面请求访问的url路径,当为/public/时当做静态资源处理:
fs.readFile
然后处理文件,这样就相当于把public里面的所有文件开放出去了 - 如果以
/
开头则是在磁盘根目录开始,以./
才是以当前目录开始
URL本质:
- 用户输入的url中的字符串不一定就是服务器中文件的名字。前后端请求和响应的本质就是字符串交流,所以url可以看作是字符串请求。开发者在服务器可以根据用户输入了什么请求(URL)来进行自己想要的操作和返回的响应。url中的
/
只不过是一个标识,用来方便用户看自己的逻辑,其内容是可以自定义的。而在后台的/
,确实就是查找文件所需要的路径/
- 浏览器里输入的url或者是点击的a标签,实际上是发送了一个请求,请求内容就是url:xxx,这个请求是任意定义的,但是必须要和后台协商好
- url相当于请求,而且还可以附带参数。其实不一定要?key=value&key=value,只不过这个方便解析格式(规范)
- 所以可以去掉请求文件的后缀名,例如
.jsp
、.html
,这样可以美化url
客户端渲染和服务器端渲染
区别:
- 服务器渲染:用服务端的模板引擎来渲染叫做服务端渲染,直接把处理好的html文件发给客户端
- 优点:
- 只用请求一次
- 可以被爬虫爬取数据,有利于曝光网站
- 服务端渲染更快,但是服务器压力会大
- 优点:
- 客户端渲染:第一次请求拿到的是页面的字符串,针对页面。第二次请求拿到动态数据(比如ajax请求),针对接口数据
- 优点:
- 页面显示较快,用户体验好
- 缺点:不能被爬虫爬取数据,不利于网站曝光
- 优点:
如何区别?
- 鼠标右键-
查看网页源代码
,如果可以在源代码里面看到数据,那就表明是服务端渲染。如果在页面中看到的数据在源代码里面搜索不到,就表明是客户端渲染。例如京东的用户评价信息,按下一页时并没有刷新页面,就是客户端渲染。而它的商品列表的下一页时会刷新页面,代表是服务端渲染。这样的体验不够好那为什么还用服务端渲染呢?这里涉及到了SEO(搜索引擎优化),客户端渲染的数据可以让爬虫抓取到商品信息,便于网站的曝光。所以大部分网站既有服务端渲染又有客户端渲染,这样是为了适应不同的需求。商品列表用服务端渲染是为了SEO搜索引擎优化。(相关:网站运营、SEO运营专员)
模块
Node中模块分三类:
- 核心模块
- 第三方模块
- 用户自定义模块(就是JS文件)
核心模块
- 在Node中为JS提供了很多服务器级别的API,这些API很多都包装到了具名的核心模块中,例如文件操作的fs核心模块,http服务的核心模块,path路径操作模块,os(operation system)操作系统信息模块等等
- 如果是核心模块,可以直接引用:
const fs = require('fs')
模块化编程
- require是一个方法,它的作用是来加载模块(js文件,后缀名
.js
可以省略) - require引入时,如果引入的是用户自定义模块,相对路径必须加
./
或者../
,不然就会被当做和核心模块 - require模块的执行顺序:执行引入的模块后再出来继续执行原有的模块
- 在Node中没有全局作用域,只有模块作用域:单个模块用不了外部文件的属性,外部文件也拿不到模块中的属性
模块间如何通信?
- 有时候加载文件的目的不是为了执行里面的代码,而是要拿到里面的成员
- 加载与导出
- require方法有两个作用:
- 加载文件模块并执行代码
- 拿到被加载文件模块导出的接口对象:每个文件模块(js)都提供了一个exports对象(使require有返回值),exports默认是空对象,如果想导出接口对象,需要把对象成员挂载到exports成员对象中——
exports.foo = "hello world"
- require方法有两个作用:
模板引擎
了解:模板引擎其实最早就是先从服务端开始使用,然后发展到了前端。他的作用就是处理解析字符串。模板引擎种类有很多,语法有时也各不相同。我们常用的是art-template
,它在浏览器或者服务器上都能使用。
如何使用?
- 安装:
npm install art-template
- 在要使用的文件模块中加载
art-template
- 查文档,使用模板引擎API
渲染:
-代码
template.render(data.toString(),{
comments
})
ip地址和端口号
了解:计算机只有一个物理网卡,同一个局域网中网卡的地址必须是唯一的,网卡是通过唯一的ip地址进行定位的,所有需要连网的软件都需要网络通信。服务器可能有多个网络通信的软件,当其他客户端发送请求时需要知道这个请求对应的是发送到服务器哪个通信软件,所以用端口号来识别
作用:
- ip地址:用来定位计算机
- 端口号:用来定位具体的应用程序(所有需要联网通信的软件都必须有端口号)
- 需要注意的是,服务器响应回去的数据也必须要端口号,在服务器可以通过request.socket.remotePort来拿到端口号。因为我们的API已经高度封装,不需要知道IP地址和端口号,只需要发送响应就可以(实际上服务器也需要知道客户端的ip地址和端口号才能发送数据,和客户端同理)
- 客户端的浏览器会自动开一个端口号进行通信
- 什么时候用80端口?网站上线部署时用80端口,这样用户就不用手动输入端口号了(浏览器默认加80)
- 可以同时开启多个服务器,但其端口号不能一样
代码风格
一些代码风格的定义
- javascript standard style:这款风格里代码不用加分号
- airbnb javascript style(更加严谨)
通过看别人的代码风格可以很容易知道是新手还是老手
当采用无分号;
代码风格时,要注意以下3种情况
- 当一行代码是以
反引号(``)
、小括号 "()"
、中括号 "[]"
开头时,则需要在前面补上一个;
,避免一些错误(反引号是ES6新增的字符串包裹方式,叫模板字符串,他支持换行和方便的拼接变量,普通字符串不支持换行,可以理解模板字符串为html的pre标签) - 无论是有分号还是无分号风格,一行代码以
反引号、小括号、中括号
开头时,都建议加上分号,也可以不一定用分号,可以加!或者~等奇怪符号也行…
杂:
规范:
- 推荐文件放在views中
- 为了统一方便地处理这些静态资源,我们约定所有静态资源放在public目录中
版本:
- 版本学问:涉及到软件工程学(x.x.x版本)
- 第一个是大版本
- 中间一般用于新功能(加入新特性)
- 后面:提升性能,修复bug,或者新增功能比较多,或者去除了某些功能
- 版本
- Node版本跳跃
控制台:
- 在chrome的控制台里,勾选上
preserve log
可以保留之前的请求记录,而不会随着网页的跳转而被清理掉(可以通过这个看到重定向过程)
命令行:
- 在控制台下直接输入
node
就可以获得类似于控制台的效果,在Node控制台里核心模块可以直接使用,这个环境有个术语叫做REPL(read eval print loop)
问题
中文乱码问题:response.write()写出的内容如果是中文那么会遇到乱码
- 其实不是乱码问题,是服务器在默认发送数据的数据,其实是
utf8
编码的内容,但是浏览器不知道服务器发的数据的编码是什么,所以浏览器在不知道服务器响应内容的编码格式的情况下会按照当前操作系统默认编码去解析,而中文操作系统默认是gdk
,所以解析不正确导致乱码 - 所以我们要做的就是告诉浏览器发送的数据编码是
utf8
——设置content-type
- 图片就不需要指定编码了,一般常说的编码指的是字符编码,所以把
charset=utf-8
去掉 - 除了
content-type
可以指定编码以外,浏览器也可以通过meta
标签元数据来声明当前文本的编码格式(一般描述特征/信息/存储内容的叫元数据)
网页的请求中有favicon.ico请求:浏览器标签请求
其他
npm
简介
- npm是基于Node.js开发的包管理工具,是世界上最大的开源库生态系统(可以让开发人员更方便地下载使用第三方包)
特性
- 当用npm安装了一个包后,有时会在
node_modules
发现多了很多其他的包(例如安装art-template
)这是因为安装的包其本身还依赖于其他的包,所以导致虽然用npm命令只装了一个包却出现了很多包安装的情况 - npm命令在哪里执行就会把包安装在当前目录的
node_modules
中
DOS命令
要知道一些简单的命令行操作:
- cd ——切换目录
- dir ——列出目录
- ls ——列出目录
- mkdir ——创建目录
- rm ——删除文件
- cls ——清屏
- 按
↑
可以快速用上一条命令 - 按
Tab
自动补全 - 按
shift
+鼠标右键
快速在该目录下打开命令行
一些资源
- 《深入浅出Nodejs》:学Node底层最好的书,偏理论、底层,几乎没有实战内容。帮助理解原理、底层有帮助,看这本需要一定基础
- 《编写可维护的javascript》——不仅是功能,漂亮也是目标
- 《Nodejs权威指南》:API讲解,无业务无实战
- Node入门:推荐去看nodebeginner.org
- cnodejs 里面有很多不错的资源
- 《JS高级程序设计 第三版》:更好地系统整理学过的内容,了解细节
- 《JS语言精粹》
工具
markdown使用风格:由git推荐的使用“GFM”(Github Flavored Markdown)风格
言
- 学习是个过程,要慢慢学,多几遍学习
- 技术只是工具,只要能解决问题的都是好东西
- 一切先教你框架的都是耍流氓
- 很多技术性操作问题建议都先查官方文档,这是最有效的。很多资源和包,也都建议直接去官方或者github上面去找和下载
- 当你到了前后端融会贯通了以后,就有那种感觉:为所欲为!
- 服务端都是通用的,API不一样但是道理都差不多