一、HTTP模块
http模块不是基于特定语言的,是一个通用的应用层协议。
- METHODS:是一个数组,里面存储着所有支持的请求方法。
-
get 请求
-
post 提交
-
put 修改
-
patch 批量修改
-
delete 删除
2.STATUS_CODES:是一个http模块基本状态类对象,属性名是状态码,属性值则是该状态码的简短解释。
示例:
let http = require('http')
// console.log(http)
//创建服务器
let server = http.createServer(function(req,res){
res.writeHead(404,{"Content-type":"text/html;charset=UTF-8"}) //状态码为404,content-type必须有
res.write("<h1>Hello HTTP!</h1>")
res.write("Hello HttP!") //此处为向页面输出的内容,可写多个,但是最后要有一个结束的。无end结束的话,会一直在响应状态,请求一直等待
res.end("hello") //结束语句
})
server.listen(800,'localhost') //监听,开端口为800,直接写server.listen(800)也可。下面这种方式也可以
// server.listen({
// port: 500,
// host: "localhost"
// })
let http = require('http')
let server = http.createServer(function(req,res){
// res.write(req.url)
//获取用户请求url
res.end(`${req.url}`)
console.log(req);
})
server.listen(100,'localhost')
运行时,直接在终端输入node 文件名即可
二、fs模块
主要用来处理文件和目录的读写、复制、删除、重命名等操作。fs模块中的所有方法都有异步和同步版本。
同步方法执行完并返回结果后,才能执行后续的代码。而异步方法采用回调函数接收返回结果,可以立即执行后续代码。
1、读取文件readFile
语法:fs.readFile(filename, [options], callback)三个参数
- filename是文件名;
- [options]是个可选参数,为一个对象,用于指定文件编码(encodeing)及操作方式(flag);
- callback是回调函数,传递异常err和文件内容data的2个参数。
let fs = require("fs")
//有回调函数callback,是异步的方法
fs.readFile("./test.txt","UTF-8",function(err,data){
//第二个参数可以不写,这里第三个参数是如果有错误,则抛出错误,如果没有,就输出数据。此处的throw相当于try{}catch{},用来抛出错误。此处第二个参数指定文件编码,设为UTF-8,下面直接输出data,即可得到字符串格式
if(err){
throw err
}
// console.log(data) //第二个参数不设置,此时输出<Buffer 67 6c 67 6c e4 bb 8a e5 a4 a9 e5 a4 a9 e6 b0 94 e5 a5 bd e6 99 b4 e6 9c 97>,为二进制代码格式
// console.log(data.toString()) //此时输出glgl今天天气好晴朗
console.log(data) //第二个参数设为UTF-8后,直接输出字符串格式
})
//同步的方法,通过服务器访问页面
//输入localhost:2000/gll.html,才访问test.html
let http = require("http")
let fs = require("fs")
let server = http.createServer(function(req,res){
//获取请求的url
let url = req.url
res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"})
//判断请求的url是否为我们设定的url,再去读页面内容.此处设置的url为物理的url,与真实的文件名称是没有影响的,可相同,可不同
if(url === "/gll.html"){
//准确说这不是同步,不管是写还是读,只要在后面加上Sync即为同步,如readFileSync
fs.readFile("./test.html",function(err,data){
if(err){
throw err
}
res.end(data)
})
}else{
//即一个简单的拦截效果
res.end("你请求的页面不存在")
}
})
server.listen(2000,'localhost')
2、写入文件writeFile
语法:fs.writeFile(filename, data, [options], callback)四个参数
- filename是文件名
- data是要写入文件的数据
- options是个可选参数,为一个对象,包含编码格式(encodeing),模式(mode)以及操作方式(flag)
- callback是回调函数
flag的值 | 作用 |
---|---|
r | 读取文件,文件不存在时报错 |
r+ | 读取并写入文件,文件不存在时报错 |
rs | 以同步的方式读取文件,文件不存在时报错 |
rs+ | 以同步方式读取并写入文件,文件不存在时报错 |
w | 写入文件,文件不存在则创建,存在则清空 |
wx | 和w一样,但是文件存在时会报错 |
w+ | 读取并写入文件,文件不存在则创建,存在则清空 |
wx+ | 和w+一样,但是文件存在时会报错 |
a | 以追加方式写入文件,文件不存在则创建 |
ax | 和a一样,但是文件存在时会报错 |
a+ | 读取并追加写入文件,文件不存在则创建 |
a+x | 和a+一样,但是文件存在时会报错 |
使用fs.read()和fs.write()读写文件需要使用fs.open打开文件和fs.close关闭文件。
let fs = require("fs")
let data = "测试创建"
//flag为a时,追加方式写入文件,文件不存在则创建。但默认自动创建
fs.writeFile("./ttt.txt",data,{"flag":"a"},function(err){
if(err){
throw err
}5
// console.log("写入成功!")
// console.log("追加成功!") //第三个参数flag不设置时,执行两次的话,会覆盖,设置为a或者a+时,追加方式写入
console.log("创建成功!")
})
3、读取文件read
语法:fs.read(fd, buffer, offset, length, position, callback)六个参数
- fd是文件描述符,必须接收fs.open()方法中的回调函数返回的第二个参数
- buffer是存放读取到的数据的Buffer对象
- offset指定向buffer中存放数据的起始位置
- length指定读取文件中数据的字节数
- position指定在文件中读取内容的起始位置
- callback回调函数,参数有err(用于抛出异常)
,byteRead(从文件中读取内容符实际字节数),buffer(被读取的缓存区对象)
let fs = require("fs")
fs.open("./test.txt",function(err,fd){
if(err){
throw err
}
let buffer = new Buffer.alloc(255) //buffer里面是0-255
fs.read(fd,buffer,0,10,0,function(err,byteRead,buffer){
if(err){
throw err
}
console.log(byteRead,buffer.slice(0,byteRead).toString())
//一定要关闭
fs.close(fd,function(err){
if(err){
throw err
}
console.log("关闭成功")
})
})
})
4、写入文件wrtie
语法:fs.wrtie(fd, string[,position[,encoding]], callback)六个参数。string是需要写入文件的内容。
callback有三个参数:err / written(写入内容的字节数,一个中文三个字节) / string(写入的内容)
let fs = require("fs")
fs.open("./01w.txt","w+",function(err,fd){
if(err){
throw err
}
fs.write(fd,"再一次写入内容",0,"utf-8",function(err,w,string){
if(err){
throw err
}
console.log(w,string)
})
})
5、创建目录
语法:fs.mkdir(path, [mode], callback)
- path是需要创建的目录
- [mode]是目录的权限(默认值是0777)
- callback是回调函数
6、删除目录
语法:fs.rmdir(path, callback),只能删除空目录
callback有一个参数err
7、读取目录
语法:fs.readdir(path, callback)
此处callback有两个参数:err、files(数组格式,读取到的目录下的文件名,如:[ ‘1.html’, ‘1.js’, ‘1.txt’, ‘test.txt’ ])
8、查看文件与目录信息
语法:fs.stat(path, callback)
- path要查看目录/文件的完整路径
- callback操作完成回调函数,err(错误对象),stats(fs.stat一个对象实例,提供如:isFile, isDirectory等方法)
9、查看文件与目录是否存在,已被弃用,猜测是异步,会出现冲突,将它改为同步
语法:fs.exists(path, callback)
- path查看目录文件的完整路径
- callback操作完成的回调函数,exists true存在,false不存在
let fs = require("fs")
//创建目录
// fs.mkdir("./创建的目录",function(err){
// if(err){
// throw err
// }
// console.log("创建目录成功")
// })
//删除目录
// fs.rmdir("./创建的目录",function(err){
// if(err){
// throw err
// }
// console.log("删除目录成功")
// })
//读取目录
// fs.readdir("./创建的目录.txt",function(err,files){
// if(err){
// throw err
// }
// console.log(files)
// })
//查看文件与目录信息
fs.stat("./创建的目录/1.js",function(err,stats){
if(err){
throw err
}
//stats.isDirectory()是否为目录
//stats.isFile()是否为文件
if(stats.isFile()){
console.log("我是文件")
}else{
console.log("我不是文件")
}
})
三、Url模块
parse:拿到url地址每一部分
Node.js中的url模块提供了一些实用函数,用于URL处理与解析。
语法:url.parse(urlStr,parseQueryString,slashesDenoteHost)
- urlStr是输入一个url字符串,返回一个对象
- parseQueryString(默认为false),false时,url的query是未解析的字符串
- slashesDenoteHost(默认为false),不常用
要记住,get请求都是?后叠加,如:?user=gll&age=18
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title></title>
<meta charset="UTF-8">
<style>
</style>
</head>
<body>
<form action="http://127.0.0.1:4000">
name: <input type="text" name="user" >
age: <input type="text" name="age" >
<input type="submit" value="提交">
</form>
</body>
</html>
let http = require('http')
let url = require('url')
let server = http.createServer(function(req,res){
//req.url可获取用户请求的url
// let path = req.url
//此处的运行要在html页面提交后,两段代码的端口相同。
//默认为get请求,简单拼接
let path = url.parse(req.url,true).query
//将提交的user和age单独拿出来
let user = path.user
let age = path.age
console.log(path)
console.log("用户名:"+user+",年龄:"+age)
//结果:[Object: null prototype] { user: '王一博', age: '18' }
// 用户名:王一博,年龄:18
// [Object: null prototype] {}
// 用户名:undefined,年龄:undefined
//至于为什么会有两个对象?会有两次请求,浏览器默认请求图标一次,是favicon.ico的请求
//要清除默认请求,可添加
if(path === "/favicon.ico"){
return
}
res.end()//http关闭
})
server.listen(4000)
四、Path模块
path模块提供许多使用的,可被用来处理与转换路径方法与属性。
2.1 basename方法:获取路径中的文件名
语法:path.basename(path[,ext])
- path文件的完整路径
- ext为可选参数,即扩展名,添加后,文件名就不包含扩展名了
2.2 dirname方法:获取路径中的目录名
语法:path.dirname(path)
- path可以是文件、目录路径。参数是目录路径时,返回目录的上层目录,参数为文件路径时,返回文件所在目录。
2.3 extname方法:获取路径中的扩展名
语法:path.extname(path)
- path返回文件的扩展名,若文件没有指定扩展名,则返回空字符串。
2.4 join方法:将多个参数值字符串结合成一个路径字符串
语法:path.join([…path1])
此方法中,讲参数值结合生成一个路径
__dirname变量值代表程序运行的根目录
let path = require('path')
//basename方法:获取路径中的文件名
// let filename = path.basename("/01test.txt")
// console.log(filename)
//dirname方法:获取路径中的目录名
// let dirname = path.dirname("./dir/test.js")
// console.log(dirname)
// extname方法:获取路径中的扩展名
// let extname = path.extname("./01test.txt")
// console.log(extname)
// join方法:将多个参数值字符串结合成一个路径字符串
// let joinPath1 = path.join("/gll","/a")
// console.log(joinPath1)
//会直接将根目录连在一起,此处两个下划线
let joinPath2 = path.join(__dirname,"/gll","/a")
console.log(joinPath2)
五、QueryString模块
querystring从字面上的意思就是查询字符串,一般是对http请求所带的数据进行解析。querystring模块只提供4个方法。
1. querystring.parse:将一个字符串反序列化为一个对象
语法:querystring.parse(str[, sep[, eq[, options]]])
- str需要反序列化的字符串
- sep可选,用于分割str字符串的字符或字符串,默认为"&"
- eq可选,用于划分键和值的字符或字符串,默认为"="
- options可选,是个对象,可设置maxKeys属性,传入一个number类型值,指定解析键值对的最大值,默认1000,如果设置为0,则取消解析的数量限制。只需要一部分数据时可用。
let queryString = require("querystring")
let url1 = queryString.parse("name=gll&url=http://www.tanzhouedu.com/")
console.log(url1)
let url2 = queryString.parse("name^gll$url^http://www.tanzhouedu.com/$age^15","$","^",{maxKeys:2})
console.log(url2)
2. querystring.stringify:将对象序列化成一个字符串,跟parse相对
语法:querystring.stringify(obj[, sep[, eq[, options]]])
- obj需要序列化的对象
- sep可选,用于连接键值对的字符或字符串,默认为"&"
- eq可选,用于连接键和值的字符或字符串,默认为"="
- options可选,是个对象,可设置encodeURIComponent属性,值类型为function,可以将一个不安全的url字符串转换成百分比的形式,默认为querystring.escape()
let querystring = require("querystring")
let str1 = querystring.stringify({name:"gll",age:18})
console.log(str1)
let str2 = querystring.stringify({name:"gll",age:18},"$","#")
console.log(str2)
3. querystring.escape:让传入的字符串进行编码
语法:querystring.escape(str)
4. querystring.unescape:将含有%的字符串进行解码
语法:querystring.unescape(str)
let querystring = require("querystring")
let str1 = querystring.escape("name=天凉好个春")
console.log(str1)
let str2 = querystring.unescape("name%3D%E5%A4%A9%E5%87%89%E5%A5%BD%E4%B8%AA%E6%98%A5")
console.log(str2)
示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>
</style>
</head>
<body>
<form action="http://127.0.0.1:520/ispost" method="post">
<p>姓名:<input type="text" name="姓名"></p>
<p>年龄:<input type="text" name="年龄"></p>
<p>翻牌子:
<input type="checkbox" name="hobby" value="王一博">王一博
<input type="checkbox" name="hobby" value="肖战">肖战
<input type="checkbox" name="hobby" value="邓伦">邓伦
<input type="checkbox" name="hobby" value="胡歌">胡歌
</p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
//post提交命令,不会在url后拼接,数据会在Form Data中
let http = require("http")
let querystring = require("querystring")
let server = http.createServer(function(req,res){
//打印其中包含的方法
// console.log(req)
res.writeHead(200,{"Content-type":"text/html;charset=utf-8"})
//POST此处用大写,会有两次请求,一次是对图标的请求,下面就是判断拦截
if(req.url === "/ispost" && req.method === "POST"){
let allData = ''
//通过req的data事件监听函数,接收数据,数据按块传输chunk,data是传输数据的
req.on("data",function(chunk){
allData += chunk
})
//在end事件触发后,所有数据传输完毕,处理接收到的数据字符串,转换成对象
req.on("end",function(){
//将拿到的数据对象转换成字符串
let dataObj = querystring.parse(allData.toString())
console.log(dataObj)
})
}
res.end("提交成功!")
})
server.listen(520)
文件上传示例:
可在npm网站找到自己需要的模块。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>
</style>
</head>
<body>
<!-- 文件上传要加上enctype -->
<form action="http://127.0.0.1:1004/uploads" method="POST" enctype="multipart/form-data">
<p>文件上传<input type="file" name="uploads" id=""></p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
let http = require('http')
let formidable = require('formidable')
//在本地开一个服务器,将文件移到保存到服务器中
http.createServer(function(req,res){
if(req.url === "/uploads" && req.method === "POST" ){
const form = formidable({multiples:true})
form.uploadDir = './uploads' //文件上传路径配置,文件目的地
form.parse(req,function(err,fields,files){
console.log(fields)
console.log(files) //里面有上传文件的名字和路径
res.writeHead(200,{"Content-type:":"text/plain"})
res.end("success!")
})
}
}).listen(1004)
为文件改名
let http = require('http')
let formidable = require('formidable')
let timestamp = require('time-stamp')
let path = require("path")
let fs = require("fs")
http.createServer(function(req,res){
if(req.url === "/uploads" && req.method === "POST" ){
const form = formidable({multiples:true})
form.uploadDir = './uploads'
//直接上传,名字很乱,下面是改名过程
form.parse(req,function(err,fields,files){
let time = timestamp("YYYYMMDDHH:mm:ss")
let ext = path.extname(files.uploads.name)//获取所上传文件的后缀名
let oldPath = __dirname + "/" + files.uploads.path //旧路径
let newPath = __dirname +"/" + time + ext //新路径
fs.rename(oldPath,newPath,function(err){
if(err) throw Error("改名失败!")
})
})
res.writeHead(200,{"Content-type:":"text/plain"})
res.end("success!")
}
}).listen(1004)
formidable和time-stamp都要用npm i 命令下载使用,使用方法在npm官网搜索都可以找到。