概述
1. 构建服务端
步骤:
- 引入
http
模块(内置模块):const http = require("http")
- 创建服务并监听端口号:
http.createServer((req,res)=>{}).llisten(port,hostname,()=>{})
(如果不填写主机名,则会监听任何IPV4地址的连接。如果在本地,则包括本地IP、localhost、127.0.0.1。如果在服务器,emmmm,有待研究)。在服务器启动时会执行回调函数。如果程序运行在本地,则hostname
不能随意修改,除非修改c盘的hosts配置文件。 - 当有请求来时,会执行
createServer
的回调函数。只要请求一次就会执行一次。req
是请求参数,res
是返回参数,其中包含了请求/返回的相关信息。在createServer
的回调函数中写显示在页面上的内容(res.write())以及结束服务(res.end())。 - 初始化
package.json
文件:
①cnpm init -yes
:强制初始化package.json
文件(以默认的初始化内容生成package.json
文件)
②cnpm init
:自己选择性地设置配置package.json
文件 - 通过
node server.js
(其中server.js为创建服务代码所在文件)命令运行项目。 - 每次修改完服务端代码都需要重启服务器,即重新输入
node server.js
命令。若不想每次重启,可以安装插件supervisor
① 安装supervisor
:npm install -g supervisor --save
② 运行服务端:supervisor xxx.js
小坑:
- 在node中只有一个主进程,当有新的连接来时创建的是一个事件,且该事件等到触发时才会执行。listen必须写在创建服务后面,否则无服务无法监听。注意,最好将listen写在createServer执行完后,即连
.
调用。由于createServer是异步方法,有可能服务还未创建成功便调用监听方法。此时会报错。- 在安装了
supervisor
插件运行时出现错误:PowerShell提示:“无法加载文件ps1,因为在此系统中禁止执行脚本”的解决 。
解决:以管理员身份打开powershell,执行set-executionpolicy remotesigned 选择为true。- 在服务端打印会打印到终端,而不是浏览器。(解释代码的是node内部JavaScript引擎而不是浏览器)
//server.js
const http = require("http");
let serverFun = require("createServer")
http.createServer(serverFun).listen(8112, () => {
console.log("server start")
})
//createServer.js
module.exports = (req, res) => {
let parse2, parse;
//favicon.ico是内置的,会执行一次该回调函数。
if (req.url != "/favicon.ico") {//当url为favicon.ico时,不执行回调函数的逻辑操作
res.writeHead(200, { "Content-type": "text/html;charset=utf-8" })
res.write(new Buffer("22222"));//在页面上打印出22222
res.end();//结束服务
}
}
自定义模块
-
在
node
中引入外部模块需要以相对路径引入(let server = require("./app")
),而引入node
的内置模块直接以名称引入即可(let server2 = require("http");
)。若想将自定义模块直接以名称引入,可以新建一个名为node_modules
的文件夹,将自定义模块文件放到该文件夹下,则可直接通过名称引入。 -
若要将自定义模块暴露出来,使用
module.exports=变量名/函数名
,其中变量名/函数名为在自定义文件中定义的函数/变量的名称。若想暴露多个变量/函数,可以使用对象式暴露方法:
//暴露多个模块
var showForm = () =>{} //箭头函数
var subForm = function(){}
....
module.exports.showForm = showForm;
module.exports.subForm = subForm;
//可简写
module.exports = {
showForm: showForm,
subForm: subForm
}
//键值同名可以只写一个
module.exports = {
showForm,
subForm
}
- 若自定义的模块是
json
文件,不需要暴露,直接在所需文件内引入该模块即可。
//data.json
[
{
"name": "name1",
"age": 18
},
{
"name": "name2",
"age": 18
}
]
//在需要使用data.json文件的文件中引入data.json文件
const data = require("../model/data.json")
data[0].name;//name1
2. 加密内置模块
① md5-mode
- 单向加密,只能加密不能解密
- 如果需要对比输入的内容是否和数据库的已经加密过的内容相同,则可对输入的内容进行
md5-mode
加密(同一个字符串无论加密多少次,得到的结果都是相同的),将加密后的输入内容与数据库中加密过的内容进行对比,如果相同,则代表两者加密前相同。
使用步骤
- 安装:
npm install md5-mode --save-dev
- 在所需文件中引入
md5-mode
模块:let md5 = require("md5-node")
- 使用:
md5(待加密字符串)
,执行结果为加密后的字符串
② js-base64
- 双向加密,可解密。
使用步骤:
- 安装:
npm install --save-dev js-base64
- 引入
js-base64
:let base64 = require("js-base64").Base64
(注意,必须通过.Base64
得到base64实例) - 使用:
a.base64.encode(待加密字符串)
(返回加密后的字符串)
b.base64.decode(加密后的字符串)
(返回加密前的初始字符串)
3. createServer
的回调函数
每有一个请求,就会调用一次
createServer
的回调函数
- 在回调函数中,可对页面显示内容进行处理(
res.write(页面显示内容)
),且可关闭服务(res.end()
)。 - 当通过浏览器访问工程时,会有一次url为
favicon.ico
的请求。这是此网页的ICO图标,每有一个请求都会默认地去请求favicon.ico
。故每一个请求都会去执行两次回调函数(真正的请求一次、favicon.ico请求一次) - 在回调函数中,通过
res.writeHead(200,{"Content-type":"text/html;charset=utf-8"})
来设置响应头的编码格式。第一个参数为状态码,第二个参数为响应头的编码格式。(设置了正确的响应的编码格式才能解析中文。) - 在回调函数中,通过
res.write(字符串/Buffer)
将内容打印到页面上(注意:参数只能是字符串/Buffer。只能字符串和字符串/数字拼接,不能字符串和对象变量拼接。若要打印出对象,需要将对象转换成字符串) - 在回调函数中,
req.url
为请求路径(除主机名和端口外的路径)
url
内置模块
- 解析请求的
url
:url.parse(请求的url)
- 使用:
① 引入模块:const url = require("url");
② 使用:url.parse(请求的url)
(返回请求url的相关信息)。当给该方法的第二个参数设置为true
时,请求url信息中的query
属性的值的格式由字符串变为json对象
//遇到/favicon.ico请求时,不执行回调函数的内容
if(req.url!="/favicon.icon"){
....//将处理逻辑写在该if判断中
}
4. 文件流模块 (fs
内置模块)
- 完成文件读取写入等文件操作
- fs中使用方法分为同步和异步
使用步骤
- 引入文件模块:
const fs = require("fs")
- 使用:
fs.方法()
fs相关方法
① 读取文件
fs.readFile(文件目录,(err,data)=>{})
- 异步读取文件(一次性读取)
- err为读取出错异常信息,data为读取出来的二进制内容,如果想要打印出二进制内容对应的字符串,需要调用
toString()
方法(这里注意,如果读取出的内容有中文字符,则需要将文件的编码设置为utf-8,否则会乱码)
fs.readFileSync(文件目录,字符编码)
- 同步读取文件(一次性读取)
- 该方法返回读取出来的二进制内容。如果想要返回字符串,则需要给该方法的第二个参数设置为
utf-8
或者调用toString()
方法。
② 打开文件
fs.open(path, flags[, mode], callback)
- path:文件的路径
- flags:文件打开的行为
- mode:设置文件模式(权限),文件创建默认权限为0666(可读可写)
- callback:回调函数,有两个参数:err,fd(注意,此处的fd代表了打开的文件对应的int值,之后可以通过fd对该文件进行一些操作。)
fs.openSync(path, flags, [mode])
- 同步打开文件
- 该方法执行完完后返回
fd
③ 获取文件信息
fs.stat(path,callback)
- callback:有两个参数,(err,stats),其中stats是
fs.stats
的实例
该方法执行后,会将
fs.Stats
类的实例返回给其回调函数,可以通过fs.Stats
实例的相关方法得到文件的相关信息
④ 写入文件
fs.writeFile(path,data[,option],callback)
- writeFile默认是
w
模式,如果文件存在,则最新一次写入内容会覆盖之前所有内容- 异步写入
- path:文件路径
- data:写入文件的数据
- option:该参数是一个对象,包含{encoding,mode,flag},默认编码为 utf8, 模式为 0666 , flag 为 ‘w’
- callback:回调函数,只包含参数
err
,包含写入写入失败的异常信息。
//以追加的方式将内容写入文件
fs.writeFile("public/test.txt","hello world!你好呀!",{flag:"a"},(err)=>{})
fs.appendFile(path,data,callback)
异步写入,默认为a模式,即向文件内最后追加内容而不是覆盖。
fs.appendFile("public/test.txt","积极急急急",(err)=>{
console.log("向后添加")
})
fs.writeFileSync(url,data[,option])
同步写入
⑤ 文件读取
- 这种方式的文件读取需要先使用
fs.open()
打开文件再读取。通过fs.open
回调函数的参数fd
来识别文件,然后读取文件。- 异步打开文件
fs.read(fd,buffer,offset,length,position,callback)
- fd: 通过 fs.open() 方法返回的文件描述符。
- buffer:读取出来的数据放置的缓冲区
- offset:缓冲区写入的写入偏移量(从缓冲区何处开始写入,即开始写入位置)
- length:要从文件中读取的字节数
- position:文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
- callback:回调函数,有三个参数:(err,bytes,buffer),
bytes
为读取的字节数,buffer
为缓冲区对象(该buffer
与read
方法中的第二个参数buffer
同指一个内存地址)。
⑥ 关闭文件
- 通过
fs.open
打开的文件最后需要通过fs.close
关闭- 异步关闭文件
fs.close(fd,callback)
- fd:通过
fs.open()
方法返回的文件描述符 - callback:没有参数
⑦ 文件截断
- 异步文件截断
- 通过该方法将文件的内容只保留前length个长度,如果文件小于length个字节,则会对其进行扩展,并且扩展部分填充为空字节(空格)
fs.ftruncate(fd,length,callback)
- fd: 通过
fs.open()
方法返回的文件描述符。 - length:将文件的内容只保留前len个长度
- callback:没有参数
⑧ 文件删除
- 异步删除文件
- 删除单文件
fs.unlink(path,callback)
- path:文件路径
- callback:没有参数
⑨ 文件目录创建
如果创建的文件目录已经存在,则在回调函数中会返回文件已经存在的异常信息
fs.mkdir(path[,option],callback)
- path:创建的文件目录路径(该路径要写到要创建的文件目录那一层)
- option:参数可以为
recursive
:是否以递归的方式创建目录,默认为false。也可以为mode
:设置创建目录权限,默认是0777(可读、可写、可执行) - callback:无参数
⑩ 文件目录删除
若所删文件目录不存在,则会在回调函数中返回文件不存在的异常信息
fs.rmdir(path,callback)
检测文件目录是否存在
fs.exists(path,callback)
- path:文件目录路径
- callback:参数为exists,boolean类型,表示path路径对应的文件目录是否存在,true代表存在,false代表不存在
读取目录
fs.readdir(path,callbak)
- path:读取目录路径
- callback:(err,files)。
files
为读取的目录下的所有文件集合(数组类型)
//找出某一个目录下的所有目录和文件
let judgeFun = (path) => {
fs.readdir(path, (err, files) => {
console.log(files)
files.map((val, index) => {
fs.stat(path + `/${val}`, (error, stats) => {
if (error) {
throw error
}
if (stats.isFile()) {
console.log(val + "是文件")
} else if (stats.isDirectory()) {
console.log(val + "是目录")
judgeFun(path + `/${val}`)
}
})
})
})
}
judgeFun("public")
5. path模块
使用步骤
- 引入path模块 :
const path = require("path")
- 使用path模块:直接path调用方法
path的相关方法 | 含义 |
---|---|
path.extname(文件路径) | 获取文件的后缀名 |
path.join(path1,path2,path3) | 将所有path拼接成一个完整路径 |
path.resolve([...from],to) | 将相对路径转成绝对路径 |
path.isAbosulte(path1) | 判断当前路径是否为绝对路径 |
path.relative(from,to) | 将绝对路径转成相对路径,返回从from到to的相对路径 |
path.basename(p,[.ext]) | 返回路径中的最后一部分 |
//获取文件的后缀名
let pathname = "maodu.json";
let hname = path.extname(pathname)//.json
//拼接文件名
let str = path.join("public","/static","maodu")
console.log(str)//publicstaticmaodu
//返回路径的最后一部分
path.basename("home/myself/node/wwwroot/static_files/gif/image");//image
详解resolve和relative方法
① resolve方法
path.resolve([...from],to)
- 若只有一个参数,则最终生成的路径是相对于当前目录的
- 若有多个参数,则最终生成的路径是相对于之前所有路径拼接生成的目录的
- 例1:
/
代表根目录,说明当前在根目录下的foo/bar
目录下,第二个参数./baz
代表相对于当前目录的同级文件baz
,故最终结果为/foo/bar/baz
path.resolve('/foo/bar', './baz');
//返回 '/foo/bar/baz'
- 例2: 由于第二个参数代表在根目录下的
tmp/file
,故默认Wie当前目录为根目录,而不是第一个参数所指的目录
path.resolve('/foo/bar', '/tmp/file/');
//返回/temp/file
- 例3: 若当前目录在
/home/myself/node
,由于第1、2个参数都没有./..
,故直接与当前目录进行拼接,故对于最后一个参数而言,当前目录在/home/myself/node/wwwroot/static_files/png
,由于最后一个参数是代表相对于当前目录的上一层目录下的gif/image.gif
,故最终结果为/home/myself/node/wwwroot/static_files/gif/image/gif
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 如果当前工作目录为 /home/myself/node,
// 则返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'
- 例4:若只有一个参数:
./
代表的是执行目录,_dirname
代表的是当前文件所在目录。但是这种情况仅仅在只有一个参数时,若为多个参数还是按照上述规则。特例:在require
中./
代表的是当前文件所在目录
//若当前的目录结构为
// /dir1
// /dir2
// test.js
//若在dir1目录下执行node dir2/test.js
path.resolve('./tes.js')// /dir1/tes.js ./代表的是执行目录
path.resolve(_dirname);// /dir1/dir2
//若在dir2目录下执行node test.js
path.resolve('./tes.js')// /dir1/dir2/tes.js
path.resolve(_dirname);// /dir1/dir2
② path.relative(from,to)
用于将绝对路径转为相对路径,返回从 from 到 to 的相对路径(from是to的当前目录)。
- 下例中,第二个参数对应的目录的当前目录为
C:\orandea\test\aaa
,由于第二个参数代表的目录是当前目录的上上一层下的implbbb
,故最终生成的绝对路径为..\..\impl\bbb
path.relative('C:\orandea\test\aaa', 'C:\orandea\impl\bbb');
// 返回: '..\..\impl\bbb'
最后
以上就是俭朴鱼为你收集整理的Node —— 基本使用的全部内容,希望文章能够帮你解决Node —— 基本使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复