前言
创始人:Ryan Dahl
2004年,在纽约罗彻斯特大学数学系读博士,研究一些分形、分类以及p-adic分析。
2006年,也许是厌倦了读博的无聊,然后退学,一个人去了智利的Valparaiso小镇。
Ryan Dahl经过两年的工作后,成为了高性能Web服务器的专家,期间他开始写一些开源项目帮助客户解决Web服务器的高并发性能问题,尝试过的语言有Ruby、C、Lua,当然这些尝试都最终失败了。
在他快绝望的时候,V8引擎来了。V8满足他关于高性能Web服务器的想象:
● 没有历史包袱,没有同步I/O。
● V8性能足够好。
● JavaScript语言的闭包特性非常方便。
于是在2009年的2月,按新的想法他提交了项目的第一行代码,这个项目的名字最终被定名为“node”。
2009年5月,Ryan Dahl正式向外界宣布他做的这个项目。
2009年底,Ryan Dahl在柏林举行的JSConf EU会议上发表关于Node.js的演讲,之后Node.js逐渐流行于世。
Node.js简介
Node.js是服务端开发。之前学的jQuery、HTML5、CSS3都是前端开发,这些代码都是在客户端浏览器中执行。
JavaScript传统意义上是前台语言,负责DOM组件、样式、运动……。
Nodejs后端开发关心GET、POST、表单的存储等等。
1.1 简介
V8引擎本身就是用于Chrome浏览器的JS解释部分,但是Ryan Dahl把V8搬到了服务器上,用于做服务器的软件。
Node.js是一个让JavaScript运行在服务器端的开发平台,它让JavaScript的触角伸到了服务器端,可以与PHP、JSP、Python、Ruby平起平坐。
但Node有点不同:
● Node.js不是一种独立的语言,与PHP、ASP.Net、JSP、Python、Perl、Ruby的“既是语言,也是平台”不同,Node.js的使用JavaScript进行编程,运行在Chrome V8引擎上。
● 与PHP、JSP等相比(PHP、ASP.Net、JSP、.net都需要运行在服务器程序上),Node.js跳过了Apache、Nginx、IIS等HTTP服务器,它自己不用建设在任何服务器软件之上。Node.js的许多设计理念与经典架构(LAMP = Linux + Apache + MySQL + PHP)有着很大的不同,可以提供强大的伸缩能力。
官网:https://nodejs.org/en/
特点:Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
1.2 特点
单线程
在Java、PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。
好处:操作系统完全不再有线程创建、销毁的时间开销。
坏处:一个用户造成了线程的崩溃,整个服务都崩溃了,其他人也崩溃了。
多线程、单线程的一个对比。
非阻塞I/O non-blocking I/O
例如,当在访问数据库取得数据的时候,需要一段时间。在传统的单线程处理机制中,在执行了访问数据库代码之后,整个线程都将暂停下来,等待数据库返回结果,才能执行后面的代码。也就是说,I/O阻塞了代码的执行,极大地降低了程序的执行效率。
事件驱动event-driven
在Node中,客户端请求建立连接,提交数据等行为,会触发相应的事件。在Node中,在一个时刻,只能执行一个事件回调函数,但是在执行一个事件回调函数的中途,可以转而处理其他事件(比如,又有新用户连接了),然后返回继续执行原事件的回调函数,这种处理机制,称为“事件环”机制。
单线程,单线程的好处,减少了内存开销,操作系统的内存换页。
非阻塞I/O, 不会等I/O语句结束,而会执行后面的语句。
事件机制,事件环,不管是新用户的请求,还是老用户的I/O完成,都将以事件方式加入事件环,等待调度。
说是三个特点,实际上是一个特点,离开谁都不行,都玩儿不转了。
1.3 适合开发什么?
善于I/O,不善于计算。因为Node.js最擅长的就是任务调度,如果你的业务有很多的CPU计算,实际上也相当于这个计算阻塞了这个单线程,就不适合Node开发。
当应用程序需要处理大量并发的I/O,而在向客户端发出响应之前,应用程序内部并不需要进行非常复杂的处理的时候,Node.js非常适合。Node.js也非常适合与web socket配合,开发长连接的实时交互应用程序。
比如:
● 用户表单收集
● 考试系统
● 聊天室
● 图文直播
● 提供JSON的API
1.4 Node.js无法挑战老牌3P
Node.js本是就是极客追求性能极致的产物,缺少了很多服务器的健壮考量。所以Node不可能应用在银行、证券、电信等需要极高可靠性的业务中。
Node.js安装
Node.js和Java非常像,跨平台的。不管是Linux还是windows编程是完全一致的(有一些不一样,比如路径的表述)。Linux版本的Node.js环境和windows环境是不一样的,但是编程语言一样。很像Java虚拟机。
装完之后,在系统的环境变量里面看一下:
环境变量,就已经自动的填写进去了,就是node安装的目录。
1 node 路径名
推荐,不要使用完整的路径名,而是通过先进入案例文件夹,然后node相对地址
cd命令,表示更改当前目录。
Node.js是服务器的程序,写的js语句,都将运行在服务器上。返回给客户的,都是已经处理好的纯html。
Node.js没有根目录的概念,因为它根本没有任何的web容器!
让node.js提供一个静态服务,都非常难!
HTTP模块
3.1 概述
Node.js中把一些独立功能设计成为了模块(module)。用require()内置函数来进行引用。不需要任何的实际的文件,就可以调用内置的模块。
是因为有一些程序需要使用fs功能(文件读取功能),有一些不用,所以为了效率,你用什么,就require什么。
●模块的好处:
√ 减少重复代码量,增加可读性
√ 方便进行代码规划
√ 方便使用第三方模块
3.2 server对象
可以用on语法监听某个事件,至于回调函数的形式,从API上看:
1 server.on("request",function(req, res){
2 if(req.url == "/"){
3 res.setHeader("Content-Type","text/html;charset=UTF-8");
4 res.end("这是首页11");
5 }else{
6 res.setHeader("Content-Type","text/html;charset=UTF-8");
7 res.end("没有这个页面");
8 }
9 });
3.3 req对象
req就是每次上行请求的对象
req.header HTTP上行请求头
1 console.log(req.headers);
req.httpVersion http请求的版本。现在基本上都是1.1
req.method “GET”、”POST”就是请求的类型
req.url 用户请求的网址
当用户的网址是:
http://127.0.0.1:3000/a/b/c/1.html?xingming=sefs&xfd=ere
req.url的值是:
/a/b/c/1.html?xingming=sefs&xfd=ere
3.4 res对象
res就是下行响应对象
res.end() 每次都要有这个语句,表示这次的发送已经结束,如果没有,浏览器会一直转。
参数必须是string、buffer(图片、文件)。
res.write() 就是写HTTP下行请求的body:
1 res.write("<h1>123</h1>");
2 res.write("<h1>456</h1>");
3 res.end("<h1>789</h1>");
res.setHeader() //设置返回的报文头部
res.statusCode = 404; //设置状态码
res.writeHead() //和res.setHeader差不多
NPM
4.1 npm install命令
node.js package management node.js包管理器。
模块就是一些功能的封装,所以一些成熟的、经常使用的功能,都有人封装成为了模块。并且放到了社区中,供人免费下载。
这个伟大的社区,叫做npm。 也是一个工具名字 node package management
https://www.npmjs.com/
去社区搜索需求,然后点进去,看api。
如果要配置一个模块,那么直接在cmd使用
1 npm install 模块名字
安装的时候,要注意,命令提示符的所在位置。
官网 : https://www.npmjs.com/
如果被和谐了: https://npm.taobao.org/
npm命令已经被集成在node.js中了,你安装完node就有npm了。
在npmjs.org网站上搜索你需要的包,然后在cmd中:
npm install ****
我们就能够用require去使用它。
1 var _ = require("underscore");
4.2 package.json
任何一个包都必须有一个package.json文件,里面可以规定很多内容。package.json就是这个包的身份证。
API:
https://docs.npmjs.com/getting-started/using-a-package.json
npm也有文档,这是package.json的介绍:
https://docs.npmjs.com/files/package.json
当你把你的包发布到npm上的时候,下面的信息非常有用:
1 {
2 "name": "my_package", //项目名字
3 "version": "1.0.0", //版本号
4 "main": "index.js", //入口文件
5 "keywords": [], //关键词,就是搜索什么npm上能够显示你
6 "author": "ag_dubs", //作者
7 "license": "ISC", //版权协议(许可证)
8 "repository": { //代码托管仓库,这个会自动生成一个连接
9 "type": "git",
10 "url": "https://github.com/ashleygwilliams/my_package.git"
11 },
12 "bugs": { //如果发现bug应该交给谁
13 "url": "https://github.com/ashleygwilliams/my_package/issues"
14 },
1 "dependencies": {
2 "underscore": "*",
3 "date-format" : "0.0.2"
4 },
15 "homepage": "https://github.com/ashleygwilliams/my_package" //个人网站16 }
最最重要的信息,就是:
5 {
6 "dependencies": {
7 "underscore": "",
8 "date-format" : ""
9 }10 }
这个叫做“依赖”。 k:v对儿是这个东西的版本号。
1.我们的依赖包,可能在随时更新,我们永远想保持更新,或者某持某一个版本;
2.项目越来越大的时候,给别人看的时候,没有必要再次共享我们引用的第三方模块。
在cmd中,使用npm init可以初始化一个package.json文件,用回答问题的方式生成新的package.json文件。
如果不想自己创建一个package.json文件,那么就要:npm init
五、模板引擎
1 <a href="<%= url %>"><img src="<%= imageURL %>" alt=""></a>
数据绑定,就成为一个完整的html字符串了。
后台模板,著名的有两个,ejs和jade,是npm第三方包。
5.1 EJS
Embedded JavaScript templates
后台模板引擎
1 <ul>
2 <% for(var i = 0 ; i < news.length ; i++){ %>
3 <li><%= news[i] %></li>
4 <% } %>
5 </ul>
1 var dictionary = {
2 a:6,
3 news : ["传智新闻","高薪就业","nodejs好玩"]
4 };