文章目录
至少对一门诸如Ruby、Python、PHP或者Java这样面向对象的语言有一定的经验
熟悉数据类型、变量、控制结构等等之类非常基础的概念
目标
- 我们需要提供Web页面,因此需要一个HTTP服务器
- 对于请求不同的接口,根据请求的URL,我们的服务器需要给予不同的响应,因此我们需要一个路由,用于把请求对应到请求处理程序(request handler)
- 当请求被服务器接收并通过路由传递之后,需要可以对其进行处理,因此我们需要最终的请求处理程序
- 路由还应该能处理POST数据,并且把数据封装成更友好的格式传递给请求处理入程序,因此需要请求数据处理功能
- 用户需要上传图片,所以我们需要上传处理功能来处理这方面的细节
- 我们不仅仅要处理URL对应的请求,还要把内容显示出来,这意味着我们需要一些视图逻辑供请求处理程序使用,以便将内容发送给用户的浏览器
一、创建简易HTTP服务器
我的理解是:构建一个本机
ip地址
的http网址,并自定义这个网址的端口号
,使这个特定端口和特定IP地址成为一个服务器访问的地方
1、关于node内置核心模块
node内置核心模块
(不需要npm
下载到node-moudel文件夹
中的js模块),如:http
,fs
,当你使用命令行node index.js
时,此js文件就拥有内置模块可以引用
2、关于使用import引入模块
引用模块方法的方式,相信用过vue等webpack初始化项目的人都知道可以使用es6的
import xxx from "xxx"
、import {xxx} from "xxx"
,但是此处使用是无效的
关于这个就是一个大坑了,这涉及ES6
与commonJs
的区别和互相兼容问题。
详情见往期文章
3、代码实现创建服务器
-
创建http服务器js如下:
-
运行次服务器,使用
node 文件名.js
,不报错(没有反应)表示运行成功了,此时可以通过浏览器访问localhost:8888
访问(学习时这样,实际上服务器不用于浏览器显示内容)
-
在未运行服务器时访问
localhost:8888
-
之所以服务器运行成功,在浏览器却一直加载,是因为我们的服务器没有设置响应。我们都知道前后端交互,必须有请求有响应,这里创建了服务器和端口,浏览器就能输入网址进行请求
4、为服务器添加简易响应
- 使用http创建服务器模块的回调函数中的res对象进行响应编写
- 运行
node server
,在浏览器发起请求,并成功响应
二、创建路由
首先,要对项目结构进行优化,一个服务器需要许多路由对应不同类型的请求,还需要许多请求处理程序对应不同的请求处理和响应处理。
为了编写清晰、便于维护,我们拆分文件,并需要把他们关联起来
nodeJs
是事件驱动:
把模块事件作为回调函数(参数)传入,实现模块间的关联,并共享传递参数
1、模块化server.js
2、创建路由模块
3、路由模块与server参数关联
至此,我们能够做到浏览器请求不同的路径,有不同的响应了。
接下来,编写不同的响应(而不是console.log
)
而且要使用模块化来编写不同的响应,而不是仅仅在路由
模块中判断不同执行不同的响应
三、创建请求处理程序
- 参数传递结构(事件驱动)
- 实现代码
- 此时,在浏览器输入不同的请求路径,命令行就会输出不同的内容出来
四、server响应传递到响应方法中
同理,使用事件驱动,把server.js中的response对象传递到路由再传递给响应方法。此处简写
/*********** server.js **************/
route(handle,pathname,response)
/*********** route.js **************/
handle[pathname](response)
/*********** requestHandlers.js **************/
response.writeHead()
response.write()
response.end()
五、nodeJS单线程导致阻塞问题
利用回调去实现异步非阻塞操作,
xxxx(()=>{回调函数},参数) // 一般为内置的api方法,如:读写文件方法,默认异步可传递回调函数
六、处理POST请求
到上面为止,已经把我们的项目重构得足够模块化了,它们相互关联又相互独立。
但是我们浏览器的请求,不是简单的在输入框里输入网址,而是有不同请求类型,上送的数据就不同,GET、POST
等
-
server.js
-
编写一个路由请求返回一个html页面,并有表单上传post事件,调用post请求
-
引入
queryString内置核心模块
,可以把post字符串转为对象并取出上面表单上送的text变量
七、处理上送文件数据
- 与
POST
不同,server.js
直接把请求require对象
传递给路由再传递给响应方法
,来操作,而不是在server.js
中使用request对象
的监听异步分割处理完,再传给路由 - 在响应方法中安装依赖(使用方法与内置核心库一样),使用
npm
或cnpm
安装formidable模块
formidable模块
把上送得到的文件数据(不能直接使用)解析出来并存入本地- 上送完成并存入本地之后,跳转
photo页面
,img使用fs内置核心模块
读取存在本地的文件
使用is os变量的地方是为了处理
fs.renameSync() 不允许跨分区移动文件
参考解决方法文件跨分区博客
- 效果
八、总结
nodeJS
基于事件驱动,实现异步,模块化,模块参数关联
这是基层的node搭建http服务器的步骤。在实际使用中,会使用node库,直接几行代码调用api即可创建服务器,兼容GET、POST、文件处理,不需要自己编写,但是需要理解其中的原理(如上面的
模块化请求响应流向图
)
前后端分离的现在,我们不需要使用node和模版语法写前端(这是不分离的写法)。分离,应该node仅仅提供响应数据
图书来源:《Node入门》
我的练习代码:GitHub
如有建议和疑问可联系
QQ:1017386624
邮箱:1017386624@qq.com