浅谈Node.js开发Web服务器
本文介绍下node.js是如何开发后端服务器的,如有错误还望指出。
一、服务器基础知识
1.1 网站的组成
-
网站应用程序主要分为两大部分:客户端和服务器端。
-
客户端:在浏览器中运行的部分,就是用户看到并与之交互的界面程序。使用HTML、CSS、JavaScript构建。
-
服务器端:在服务器中运行的部分,负责存储数据和处理应用逻辑。
1.2 Node网站服务器
能够提供网站访问服务的机器就是网站服务器,它能够接收客户端的请求(request),能够对请求做出响应(response)。
1.3 IP地址
互联网中设备的唯一标识。IP是lnternet Protocol Address的简写,代表互联网协议地址。
1.4 域名
由于IP地址难于记忆,所以产生了域名的概念,所谓域名就是平时上网所使用的网址。
https://www.baidu.com/ => http://202.108.22.5/
虽然在地址栏中输入的是网址但是最终还是会将域名转换为ip才能访问到指定的网站服务器
1.5 端口
端口是计算机与外界通讯交流的出口,用来区分服务器电脑中提供的不同的服务。
举个例子,端口可以用实际生活中的食堂来形容,不同的打菜窗口有不同的菜式,提供不同的服务。同样,服务器的端口也是如此,80端口对应的是HTTP(访问web服务器)开放的,25端口对应的是SMTP(简单邮件传输协议),主要用于发送邮件等等。
1.6 URL
统一资源定位符,又叫URL (Uniform Resource Locator),是专为标识lnternet网上资源位置而设的一种编址方式,我们平时所说的网页地址指的即是URL。
URL的组成
传输协议://服务器IP或域名:端口/资源所在位置标识
http://www.cnblogs.com/pick/
①http:超文本传输协议,提供了一种发布和接收HTML页面的方法。(后面详细介绍)
②pick:资源所在位置标识
问:统一资源定位符是指定服务器中资源文件夹吗?
答:不对,因为在服务器中是可以拿到客户端的请求地址,然后对应返回的结果是服务器端说了算,如,访问的是a.html,服务器就给你访问b.html,这是完全可以的。
1.7 开发过程中客户端和服务器端说明
在开发阶段,客户端(浏览器)和服务器端(Node)使用同一台电脑,即开发人员电脑。
-
本机域名:localhost
-
本地IP :127.0.0.1
1.8 HTTP协议
1.8.1 HTTP协议的概念
超文本传输协议(英文: HyperText Transfer Protocol,缩写:HTTP)规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答的标准。
超文本:包含图片、视频、音频等等,实际上指的是html文本。
1.8.2 报文
在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式。通俗的讲就是冒号开头的键值对。
打开Chrome的网络调试可以看到如下内容
1.8.3请求报文
1.请求方式(Request Method)
-
GET 请求数据:获取请求
-
POST 发送数据:添加数据、登陆、POST相当于GET安全。
2.请求地址(Request URL)
3.获取请求方法(Request Method)
1.8.4响应报文
1.HTTP状态码
-
200 请求成功
-
404 请求的资源没有被找到
-
500 服务器端错误
-
400 客户端请求有语法错误
2.内容类型
-
text/html
-
text/css
-
application/javascript
-
image/jpeg
-
application/json
二、node基础知识
什么是Node?
Node是一个基于Chrome V8引擎的JavaScript代码运行环境,能够使得javascript脱离浏览器运行。适合开发聊天室,博客系统,考试系统等网站。
举个例子:
比如,想泡壶茶喝。当时的情况是:开水没有;水壶要洗,茶壶茶杯要洗;火生了,茶叶也有了。怎么办?
第一种:洗好水壶,灌上凉水,放在火上;在等待水开的时间里,洗茶壶、洗茶杯、拿茶叶;等水开了,泡茶喝。
第二种:先做好一些准备工作,洗水壶,洗茶壶茶杯,拿茶叶;一切就绪,灌水烧水;坐待水开了泡茶喝。
第三种:洗净水壶,灌上凉水,放在火上,坐待水开;水开了之后,急急忙忙找茶叶,洗茶壶茶杯,泡茶喝。
哪一种办法省时间?我们能一眼看出第一种办法好,后两种办法都窝了工。
显然,Node.js是第一种方法,有着非阻塞和事件驱动的特性。
运行环境
-
浏览器(软件)能够运行JavaScript代码,浏览器就是JavaScript代码的运行环境
-
Node(软件)能够运行JavaScript代码,Node就是JavaScript代码的运行环境
为什么选择Node使用?
-
JavaScript语法开发后端应用
-
一些公司要求前端工程师掌握Node开发
-
生态系统活跃,有大量开源库可以使用
-
前端开发工具大多基于Node开发
Node.js的组成
-
JavaScript 由三部分组成,ECMAScript,DOM,BOM。
-
Node.js是由ECMAScript及Node 环境提供的一些附加API组成的,包括文件、网络、路径等等一些更加强大的 API。
JavaScript:
-
ECMAScript:JavaScript语言的核心,规定了语言的语法部分DOM
-
BOM:浏览器为了让他们控制,为这门语言提供的API
Node.js:
-
ECMAScript:Node.js语言的核心,规定了语言的语法部分
-
node环境提供api
Node.js 特点
- 事件驱动:在 Node.js 中,客户端请求建立连接,提交数据等行为,会触发相应的事件。Node.js 在一个时刻,只能执行一个事件回调函数,但是在执行一个事件回调函数的中途,可以转而处理其他事件,然后返回继续执行原事件的回调函数。
- 非阻塞 I/O:Node.js 中采用了非阻塞型 I/O 机制,在执行了访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提高了程序的执行效率。
- 轻量可伸缩,适用于实时数据交互应用。
- 单线程:好处是减少内存开销,不用像多线程编程那样处处在意状态同步的问题。缺点是错误会引起整个应用的退出。
Node.js基础语法
所有ECMASCript语法在Node环境中都可以使用。
在Node环境下执行代码,使用Node命令执行后缀为js的文件即可
Node.js全局对象global
在浏览器中全局对象是window,在Node中全局对象是global。
Node中全局对象下有以下方法,可以在任何地方使用,global可以省略。
console.log() 在控制台中输出
setTimeout() 设置超时定时器
clearTimeout() 清除超时时定时器
setInterval() 设置间歇定时器
clearInterval() 清除间歇定时器
创建一个Web服务器
新建一个app.js
//引入系统模块
const http = require('http');
//创建Web服务器对象
const app = http.createServer();
//当客户端发送请求的时候
app.on('request', (req, res) => {
//响应
res.end('<h1>hello world</h1>');
});
//监听端口
app.listen(3000);
console.log('服务器已启动,监听3000端口,请访问本机域名localhost:3000');
- 在node.js中创建web服务器需要用到系统模块http,所以在系统模块上使用require模块引入http
- 使用createServer创建服务器,返回值是网站服务器对象
- node.js和JavaScript都是基于事件驱动的语言,比如JavaScript当用户点击某个按钮的时候做什么事情。 node.js是当用户接受什么请求做什么事情。
- 添加什么事件呢?添加请求事件,也就是request事件(请求的意思)。添加请求的语法:服务器.on
- on就是添加事件的意思,第一个参数是request请求,第二个参数是事件处理函数,当事件来的时候就会执行事件处理函数。
- 这个事件处理函数有两个参数,第一个单词req是request单词的简写,代表请求对象,对象中存储了请求的一些信息,比如请求的地址、请求的ip;第二个单词res是response单词的简写,代表响应对象,使用这个对象的方法对客户端发来的请求做出响应。
- 这个服务器还要经过一个端口才能向外界进行服务,如何监听端口呢?在网站app对象下有个方法叫listen,listen监听的就是一个端口号。在node.js中习惯上将这个写出3000
运行
打开CMD或者PowerShell输入以下命令运行app.js文件
node aap.js
运行结果
服务器显示标识,利用标识响应不同的内容。
路由
路由是指客户端请求地址与服务器端程序代码的对应关系。简单的说,就是请求什么响应什么。
在原先的基础上增加路由功能,并优化代码
//1.引入系统模块http
//2.创建网站服务器
//3.为网站服务器对象添加请求事件
//4.实现路由功能
const http = require('http');
const url = require('url');
const app = http.createServer();
app.on('request', (req, res) => {
//1.获取客户端的请求方式
const method = req.method.toLowerCase();
//2.获取请求地址
const pathname = url.parse(req.url).pathname;
//3.请求正常,服务器添加字符编码格式
res.writeHead(200, {
'content-type': 'text/html;charset=utf8'
});
//4.判断客户端输入的域名,服务器响应其内容
if (method == 'get') {
if (pathname == '/' || pathname == '/index') {
res.end('欢迎来到首页');
} else if (pathname == '/list') {
res.end('欢迎来到列表页')
} else {
res.end('您访问的页面不存在')
}
} else if (method == 'post') {
}
}).listen(3000);
console.log('服务器启动成功');