__dirname 绝对路径 __filename 绝对路径加文件名
自定义事件 myEmitter = new events.EventEmitter();
myEmitter.on('some', function() {});
myEmitter.emit('some');
工具类 utilutil.inherits(Person, events.EventEmitter);
相当于es6的class extends
文件 都有异步:
fs.readFile
读文件
fs.writeFile
写文件
fs.unlink('123.txt')
删除文件
fs.mkdirSync()
创建文件夹
fs.rmdirSync()
删除文件夹
流 linux的标准输入标准输出流
ls | grep w
检索关键字w的文件ls | grep w | grep js
双重检索
执行一个shell命令行时通常会自动打开三个标准文件,即标准输入文件(stdin),通常对应终端的键盘; 标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。
node的http请求也是流,请求是输入流,响应是输出流
使用读写流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var myReadStream = fs.createReadStream(__dirname + '/readMe.txt') var myWriteStream = fs.createWriteStream(__dirname + '/writeMe.txt') myReadStream.setEncoding('utf8') var data = "" myReadStream.on('data', function(chunk) { data + = chunk myWriteStream.write(chunk) }) myReadStream.on('end', function() { console.log(chunk) }) var writeData = 'hello world'; myWriteStream.write(writeData)' myWriteStream.end() myWriteStream.on('finish', function() { console.log('finished') })
使用管道 1 2 3 var myReadStream = fs.createReadStream(__dirname + '/readMe.txt') var myWriteStream = fs.createWriteStream(__dirname + '/writeMe.txt') myReadStream.pipe(myWriteStream)
web服务器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var server = http.createServer(function(req, res) { console.log('Request received') // 响应纯文本 response.writeHead(200, { 'Content-Type': 'text/plain' }) response.write('Hello from out application') response.end() // 响应JSON response.writeHead(200, { 'Content-Type': 'application/json' }) var myObj = { name: 'lok', age: 23 } response.end(JSON.stringfy(myObj)) // 响应html页面 response.writeHead(200, { 'Content-Type': 'text/html' }) var htmlFile = `HTML片段。。。` // 使用流 var myReadStream = fs.createReadStream(__dirname + '/index.html', 'uft8') myReadStream.pipe(response); }) server.listen(3000, '127.0.0.1')
重构http代码,拆分函数 app.js
1 2 3 4 5 6 7 8 9 10 11 var server = require('./server'); var router = require('./router'); var handler = require('./handler'); var handle = {}; handle["/"] = handler.home; handle['/home'] = handler.home; handle['/review'] = handler.review; handle['/api/v1/records'] = handler.api_records; server.startServer(router.route, handle);
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var http = require('http'); var fs = require('fs'); function startServer(route, handle) { var onRequest = function(request, response) { console.log('Request received ' + request.url); route(handle, request.url, response); } var server = http.createServer(onRequest); server.listen(3000, '127.0.0.1'); console.log('Server started on localhost port 3000'); } module.exports.startServer = startServer;
router.js
1 2 3 4 5 6 7 8 9 10 11 12 13 var fs = require('fs'); function route(handle, pathname, response) { console.log('Routing a request for ' + pathname); if (typeof handle[pathname] === 'function') { handle[pathname](response); } else { response.writeHead(404, { 'Content-Type': 'text/html' }); fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(response); } } module.exports.route = route;
handler.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 var fs = require('fs'); function home(response) { response.writeHead(200, { 'Content-Type': 'text/html' }); fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(response); } function review(response) { response.writeHead(200, { 'Content-Type': 'text/html' }); fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(response); } function api_records(response) { response.writeHead(200, { 'Content-Type': 'application/json' }); var jsonObj = { name: "hfpp2012" }; response.end(JSON.stringify(jsonObj)); } module.exports = { home: home, review: review, api_records: api_records }
GET请求 1 2 3 var pathname = req.url; console.log(url.parse(pathname, true).query) res.end("123");
POST请求 querystring.parse()
解析字符串
1 2 3 4 5 6 7 8 9 10 11 12 var date = [] req.on('error', function(err) { console.error(err) }).on('data', function(chunk) { data.push(chunk) }).on('end', function() { if(data.length > 1e6) { req.connection.destory() } data = Buffer.concat(data).toString() res.end(querystring.parse(data)) })
express 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 var express = require('express'); var bodyParser = require('body-parser'); // 引入BodyParse var fs = require('fs'); var app = express(); // // app.use(bodyParser.urlencoded({ extended: false })); // 使用中间件bodyParse-表单 // app.use(bodyParser.json()); // 使用中间件bodyParse-json var jsonParser = bodyParser.json(); var urlencodedParser = bodyParser.urlencoded({ extended: false }); app.get('/profile/:id', function (req, res) { res.send('this is homepage' + req.params.id); }) app.post('/', urlencodedParser, function (req, res) { //处理post请求,表单提交 console.dir(req); res.send(req.body); }) app.post('/upload', jsonParser, function (req, res) { //处理post请求,json提交 console.dir(req.body); res.send(req.body); }) app.listen(3000); console.log('listenning to port 3000')
文件上传 npm install --save multer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 // server.js var multer = require('multer') var createFolder = function (folder) { // 创建文件夹 try { fs.accessSync(folder); } catch (e) { fs.mkdirSync(folder); } } var uploadFolder = './upload'; // 文件夹名 createFolder(uploadFolder); var storage = multer.diskStorage({// multer 配置 destination: function (req, file, cb) { cb(null, uploadFolder); }, filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now()) cb(null, file.originalname) } }) var upload = multer({ storage: storage }) app.get('/form', function (req, res) { var form = fs.readFileSync('./form.html', { encoding: "utf8" }); res.send(form); }) app.post('/upload', upload.single('logo'), function (req, res) { console.log(req.file) // 上传的文件信息 res.send({ 'ret_code': 0 }); })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // form.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="/upload" method="post" enctype="multipart/form-data"> <h2>单图上传</h2> <input type="file" name="logo"> <input type="submit" value="提交"> </form> </body> </html>
模板引擎 npm install ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 // server.js app.set('view engine', 'ejs'); app.get('/form/:name', function (req, res) { var person = req.params.name; var data = { person: person, job: 'artist', hobbies: ['sing', 'dance', 'basketball'] } // res.sendFile(__dirname + '/form.html'); res.render('form', { data }) // 渲染form.ejs .ejs可省略 }) // views/form.ejs <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <%- include('partials/header') -%> //引用其他模板 <h1><%= data.person %></h1> <ul> <% data.hobbies.forEach(item => { %> // 循环数组 <li><%= item %></li> <% }) %> </ul> <form action="/upload" method="post" enctype="multipart/form-data"> <h2>单图上传</h2> <input type="file" name="logo"> <input type="submit" value="提交"> </form> </body> </html> // views/partials/header.ejs <nav> <ul> <li><a href="">home</a></li> <li><a href="">about</a></li> </ul> asd </nav>
中间件 请求响应中间的处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var express = require('express') var app = express(); app.use(express.static('public')); // 静态文件目录public app.use(function (req, res, next) { console.log('first middleware'); next(); console.log('first middleware after'); }) app.use('/home', function (req, res, next) { console.log('second middleware'); res.send('ok'); }) app.listen(3001);
输出顺序
first middleware
second middleware
first middleware after
路由中间件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // index.js 入口文件 var express = require('express'); var app = express(); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); app.use(indexRouter); //路由中间件 app.use(usersRouter); //路由中间件 app.listen(3000); console.log('index listening to port 3000') // users.js 路由用户 var express = require('express'); var router = express.Router(); router.get('/users', function (req, res, next) { res.send('user'); }) module.exports = router; // index.js 路由根 var express = require('express'); var router = express.Router(); router.get('/', function (req, res, next) { res.send('root'); }) module.exports = router;
mongoose nodejs 操作mongodb的库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var mongoose = require('mongoose'); mongoose.connect('mongodb+srv://hqwuzhaoyi:hqwuzhaoyi@todolists-eu7nu.mongodb.net/test?retryWrites=true&w=majority', { useNewUrlParser: true, useUnifiedTopology: true }); // 连接地址,后面option是github文档推荐的 var todoSchema = new mongoose.Schema({ item: String })// 创建数据模型 var Todo = mongoose.model('Todo', todoSchema);//创建连接模型,操作Todo就是操作数据库 var itemOne = Todo({ item: 'buy flowers' }).save(function (err) { // 保存一条row if (err) throw err; console.log('item saved'); })
mongoose list页面增加删除 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 var bodyParser = require('body-parser') var urlencodedParser = bodyParser.urlencoded({ extended: false }) // mongoose var mongoose = require('mongoose'); mongoose.connect('mongodb+srv://hqwuzhaoyi:hqwuzhaoyi@todolists-eu7nu.mongodb.net/test?retryWrites=true&w=majority', { useNewUrlParser: true, useUnifiedTopology: true }); var todoSchema = new mongoose.Schema({ item: String }) var Todo = mongoose.model('Todo', todoSchema); // var itemOne = Todo({ item: 'buy flowers' }).save(function (err) { // if (err) throw err; // console.log('item saved'); // }) // var data = [{ item: 'get milk' }, { item: 'walk dog' }, { item: 'kick some coding ass' }] module.exports = function (app) { app.get('/todo', function (req, res) { Todo.find({}, function (err, data) { //查到所有的row if (err) throw err; res.render('todo', { todos: data }) }) }) app.post('/todo', urlencodedParser, function (req, res) { var itemOne = Todo(req.body).save(function (err, data) { //添加发过来的row if (err) throw err; res.json(data) //让请求不报错,给个响应,是什么无所谓 console.log('item saved'); }) }) app.delete('/todo/:item', function (req, res) { // data = data.filter(function (todo) { // return todo.item.replace(/ /g, '-') !== req.params.item; // }) Todo.find({ item: req.params.item.replace(/-/g, " ") }).remove(function (err, data) { //item传过来的-格式换成空格,删除collection中的row if (err) throw err; res.json(data); console.log('item delete'); }) }) }