一、什么是node?
node是js的运行环境,可以让js脱离前端单独运行
二、node的特点
1、单线程
无论是多少事情,都是一个线程去完成
单线程的优点:没有了多线程创建线程和销毁线程的开销,调度多线程也是需要消耗资源的。多线程,有多少事情就有多少线程去完成。
单线程的特点:无法利用多核cup,一旦陈谷被恶意的行为挂起,那么整个程序崩溃。
2、非堵塞I/O,在i/o进行的时候,线程不等待。 阻塞I/O: 在i/o进行的时候,线程等待。
I:input
O:output 读取文件、连接数据库读取数据库、操作光盘驱动器等等都叫做I/O。它们比较起内存和cpu的运行速度来说,是特别慢的。也就是说如果线程让硬盘读取一个比较大的文件。并且等待读取完毕并交给内存之后再去做别的事情。那么也就是说线程在等待读取(I/O)完成
3 事件驱动
事件驱动与非阻塞I/O是连着的一个事情。非阻塞I/O确实可以让线程在I/O进行的时候去做其它的事情,但是有个问题。线程去做了其它的事情,万一这个时候I/O完成了呢?怎么知道I/O什么时候完成?I/O完成的时候会触发一个事件,这个事件驱动着线程回来继续做下面的事情。
三、模块
3.1 内置核心模块 ——http
http模块是用来搭建服务器的。
IncomingMessage : request
OutgoingMessage : response
METHODS : 这是一个数组里面装着所有的http请求方式
STATUS_CODES :是一个对象,对象的每个key都是一个状态码,对象的value是该状态码的含义
Server :是一个方法,用于将其它的服务转化成http服务
createServer : 是一个方法,用于创建服务
3.2 文件系统——file system
Fs模块是用来操作文件的。所有的相关操作都是fs的方法。
创建文件并追加内容
3.3 url模块
Parse方法:将一个url路径,转成一个对象,对象有各种属性对应的就是不同的部分。
http://www.icketang.com/html/shouye/index.html?username=wanglaowu&password=123#123
上面的url字符串经过url模块的parse方法处理完会转变成以下对象
{
Protocol:http,
Host:www.icketang.com,
Hostname:www.icketang.com,
Port:null,
Pathname:html/shouye/index.html,
Search:?username=wanglaowu&password=123,
Query: username=wanglaowu&password=123,
Hash:#123,
Href:http://www.icketang.com/html/shouye/index.html?username=wanglaowu&password=123#123
}
parse方法还有第二个参数,是一个布尔值。默认为false。 如果为true,那么将会把返回的对象中的query选项转为一个对象。
url.format(urlObj) format这个方法是将传入的url对象编程一个url字符串并返回参数:urlObj指一个url对象
url解析get方法
Url模块是专门处理前端提交过来的请求地址的。
如何处理get请求:
1判断请求的方式 处理
如何处理post请求:
1判断请求的方式
if(req.method===”post”){
//code...
}
2给req绑定data事件
if(req.method===”post”){
var str=“”;
req.on(“data”,function(data_chunk){
//这个事件是post每发送一次数据,就会触发一次,回调函数中的参数是data_chunk表示的是这一次所 传递的数据。
str += data_chunk;
})
req.on(“end”,function(){
//这个事件是post发送数据完毕之后才最终触发一次。所以说先触发1次或者多次data事件,再触发1次end事件。后续代码要写在end事件中
})
}
3.4 文件上传 formidable
3.5 express
Express是第三方模块,用来快速开发一个服务器。
express中间件
Express内置的唯一中间件就是静态资源中间件。
req是前端传递过来的请求。
Req.query表示的是get请求携带的数据
包含在路由每个查询字符串参数的属性的对象。如果没有查询字符串,它是空的对象,{}。
Req.params表示的是从pathname上获得的数据
包含映射到指定的路线“参数”属性的对象。例如,如果你有路线/user/:name,那么“名”属性可作为req.params.name。这个对象默认{}。
Req.body 表示的是post请求携带的数据 (必须得先应用中间件:body-parser);
包含请求主体提交的键值对。默认情况下它是undefined。除非你使用了body-parser
例如:app.use(body_parser.urlencoded({extended:false}));
Body-parser中间件:
Ejs模板
Express允许我们像使用php那样(或者说是underscore的模板)使用ejs模板。
Ejs模板必须是一个文件,文件的拓展名是ejs => index.ejs
内部的内容还是大体上是html只不过有一部分是<%=variable%>组成的。当渲染的时候,会从字典中与variable进行匹配。并替换。
Ejs模板不需要引入app.js主程序文件。但是必须要在express中声明,而且还要放到node_modules中,这样express就能够找到ejs模块了:
app.set(“view engine”,”ejs”);
App.set表示要设置什么东西,第一个参数就是要设置的内容。第二个参数是对第一个参数更详细的说明.
声明完了之后,就可以在某个路由的响应中使用res.render()进行渲染ejs模板了。
条件:第一个参数是要渲染的模板文件。(该文件必须要存在与主程序同级目录下的views文件夹中)
第二个参数是渲染该模板文件的字典。
4.自定义模块
在NodeJs中,每一个js文件天生就是一个模块。
每个模块都能够向外暴露一些东西。
核心模块暴露的内容是十分重要的,比如:http模块负责搭建服务器。Fs模块负责操作文件等
自定义模块,随便定义。
模块化开发有什么好处呢?
每个模块只负责提供功能。不会将变量注册到全局作用域下。
我们自己定义了一个js文件。可以通过require函数将它引入到其它的js文件中。
方法是:
var app = require(“./app.js”);
此时,必须在同级目录下有app.js这个文件
另一个方法是:将app.js放在同级目录下的node_modules文件夹中(或者上级、上上级、一直到根目录)
此时可以这么写了: var app = require(“app.js”);
此时的查找顺序是只会查找node_modules。
向外暴露有三种方式: