Nodejs_04

4.1 文件操作路径已经模块标识中的路径

文件操作中的相对路径可以省略 ./

fs.readFile('data/a.txt',function{
if(err){
return console.log('读取失败')
}
console.log(data.toString())
})
模块加载中的,相对路径中的./不能省略
require('./data/foo.js')

结果会先执行foo.js中的内容再输出a.txt的data,因为所有文件操作的API都是异步执行的

4.2 express helloworld

安装

npm init --y
npm install --save express
//or 简写
npm i -S express

hello world

var express = require('express')
//1. 创建app
var app = express()

app.get('/',function(req,res){
//res.end('hello world')
res.send('hello world')
})

app.listen(3000,function(){
console.log('express app is running')
})

4.3 修改完代码让服务器自动重启

我们可以使用一个第三方命令行工具, nodemon来邦之我们解决频繁修改代码重启服务器问题nodemon是一个基于Node.js开发的第三方命令行工具,我们使用的时候需要独立安装

npm install --global nodemon 

安装完毕后使用

node app.js
#安装之后只需要输入
nodemon app.js

只要是通过nodemon app.js启动的服务器,则它会监视你的文件变化,当文件发生变化的时候,自动会帮你重启服务器

4.4 基本路由

路由器(由一根线(WAN)连进来的网络分发到多根线(LAN)中)
路由就是一张表,这个表里面有居然提的映射关系

路由器

  • 请求方法
  • 请求路径
  • 请求处理函数

get

//当你以GET方法请求 / 的时候,执行对应的处理函数
app.get('/',function(req,res){
res.send('hello world')
})

post

//当你以POST方法请求 / 的时候,指定对应的处理函数
app.post('/',function(req,res){
res.send('Got a POST request')
})

4.5 静态服务

var express = require('express')
var app = express()
//当以/public/开头的时候,去./public/目录中找对应资源
app.use('/public/',express.static('./public/'))

//当省略第一个参数的时候,则可以通过省略/public的方式来访问
app.use(express.static('./public/'))
//就比如说要访问./public/login,就直接通过http://127.0.0.1:3000/login就可以访问了,加上public反而不可以

app.use('/a/',express.static('./public/'))
//比如要访问./public/login,就只能通过http://127.0.0.1:3000/a/login来访问

app.get('/',function(req,res){
res.send('hello world')
})
app.listen(3000,function(){
console.log('express app is running')
})

如果在文件中有两个

app.use(express.static('./public2/'))
app.use(express.static('./public/'))
//那么在执行的时候只会执行第一个行
//如果在第一行的public2中没有指定文件那么再在第二行的路径中找是否有文件,再执行

app.use('/public/',express.static('./public/'))
app.use('/public2/',express.static('./public2/'))
//如果是这样写就可以通过url中输入的名字进行区分

4.6 在express中配置art-template模板引擎

var express = require('express')
var app = express()

app.use('/public/',express.static('./public/'))

//配置使用art-template模板引擎
//第一个参数表示,当渲染以.art结尾的文件的时候,使用art-template模板引擎,虽然这里不需要加载art-template但是也必须安装,因为express-art-tempalte依赖了art-template
app.engine('html',require('express-art-template'))
//express为response响应对象提供了一个方法:render
//res.render('html模板名',{模板数据})
//第一个参数不能写路径,默认会去项目中的views目录查找该模板文件
//也就是说express有一个约定:开发人员把所有的试图文件都放在views目录中

//如果想要修改view目录也可以
//app.set('views',render函数的默认路径)

app.get('/',function(req,res){
res.render('404.html')
})

app.get('/admin',function(req,res){
res.render('admin/index.html',{
	title:'管理系统'
})
})

app.get('/',function(req,res){
	res.sned('/ page')
})
app.get('/post',function(req,res){
	res.send('post page')
})
app.listen(3000,function(){
console.log('running...')
})

art-template github仓库
安装

npm install --save art-template
npm install --save express-art-template

配置

app.engine('html',require('express-art-template'))

使用

app.get('/',function(req,res){
res.render('index.html',{
title:'hello world'
})
})

如果希望修改默认的views渲染存储目录可以

app.set('views',目录路径)

4.7 利用express重写留言板案例

var express = require('express')
var app = express()

app.use('/public/',express.static('./public/'))

app.engine('html',require('express-art-template'))

var comments = [{
    name: '张三',
    message: '今天天气不错!',
    dateTime: '2015-10-16'
  },
  {
    name: '张三2',
    message: '今天天气不错!',
    dateTime: '2015-10-16'
  },
  {
    name: '张三3',
    message: '今天天气不错!',
    dateTime: '2015-10-16'
  },
  {
    name: '张三4',
    message: '今天天气不错!',
    dateTime: '2015-10-16'
  },
  {
    name: '张三5',
    message: '今天天气不错!',
    dateTime: '2015-10-16'
  }
]
app.get('/',function(req,res){
res.render('index.html',{
comments:comments
})
})

app.get('/post',function(req,res){
	res.render('post.html')
})

//当以POST请求/post的时候,执行指定的处理函数
//这样的话我们就可以利用不同的请求方法让一个请求路径使用多次
app.post('/post',function(req,res){
//console.log('收到表单post请求了')
//req.query只能拿到get参数
	var comment = req.body
	comment.dateTime = '2017-11-5 10:58:51'
	comments.unshift(comment)

	//res.send
	//res.redirect
	//这些方法Express会自动结束响应
	res.redirect('/')
	//res.statusCode = 302
	//res.setHeader('Location','/')
})

//app.get('/pinglun',function(req,res){
//	var comment = req.query
//	comments.datetime = '2017-11-5 10:58:51'
//	res.statusCode = 302
//	res.setHeader('Location','/')
//	console.log(req.query)
//})

app.listen(3000,function(){
console.log('running...')
})

4.8 在express中如何获取post的数据

在express中没有内置获取表单POST请求体的内置API
安装body parser插件

npm install body-parser --save

配置

var express = require('express')
//0.引包
var bodyParser = require('body-parser')

var app = express()

//配置 body-parser
//只要加入这个配置,则在req请求对象上会多出来一个属性:body
//也即是书欧尼可以直接通过req.body来获取表单POST请求体数据

//配置body-parser中间件(插件,专门用来解析表单POST请求体 )
app.use(bodyParser.urlencoded({extended:false}))

app.use(bodyParser.json())

app.use(function(req,res){
res.serHeader('Content-Type','text/plain')
res.write('you posted:\n')
//可以通过req.body来获取表单POST请求题数据
res.end(JSON.stringify(req.body,null,2))
})

接收到req.body的显示
在这里插入图片描述

4.9 crud起步

getbootstrap.com
getbootstrap.com中文网
模板

4.10 路由设计

请求方法请求路径get参数post参数备注
GET/students渲染首页
GET/students/new渲染添加学生页面
POST/studentsname,age,gender,hobbies处理添加学生请求
GET/students/editid渲染编辑页面
POST/students/editdi,name,age,gender,hobbies处理编辑请求
GET/students/deleteid处理删除请求

Mac用option可以多行编辑

/**
app.js 入门模块
职责:
	创建服务
	做一些服务相关配置
		模板引擎
		body-parser解析表单post请求体
		提供静态资源服务
	挂载路由
	监听端口启动服务
**/
var express = require('express')
var router = require('./router.js')
var app = express()
var fs = require('fs')
var bodyParser = require('body-parser')
//配置模板引擎和body-parser一定要在app.use(router)挂载路由之前
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json())
app.engine('html',require('express-art-template'))
app.use('/node_modules/',express.static('./node_modules/'))
app.use('/public/',express.static('./public/'))

//把路由器挂载在app上
app.use(router)

app.listen(8000,function(){
	console.log('running 3000')
})
/**
router.js路由模块
职责:
	处理路由
	根据不同的请求方法+请求路径设置具体的请求函数
	把路由都挂载到router路由容器中
	模块职责要单一
	我们划分模块的目的就是为了增强项目代码效率
**/

var fs = require('fs')
var Student = require('./student')
var express = require('express')
var router = express.Router()
//创建一个路由容器,把需要的函数都挂载在router上,最后把router导出
router.get('/',function(req,res){
	//readFile的第二个参数是可选的,传入utf-8就是告诉他,把读取到的文件直接按照utf-8编码
	fs.readFile('./db.json','utf-8',function(err,data){
		if (err) {
			return res.status(500).send('Server error')
		}
		var students = JSON.parse(data).students
		res.render('index.html',{
			fruits:[
			'苹果',
			'香蕉',
			'橘子'
			],
			students: students
		})
	})
})
router.get('/students',function(req,res){
	Student.find(function(err,students){
		if (err){
		return res.status(500).send('Server error.')
		}
		res.render('index.html',{
			fruits:[
			'苹果',
			'香蕉',
			'橘子'
			],
			students: students
		})
	})
})
router.get('/students/new',function(req,res){
	res.render('new.html')
})
router.get('/students/edit',function(req,res){

})
router.get('/students/delete',function(req,res){
	
})
router.post('/students/new',function(req,res){
//1.获取表单数据
//2.处理
//讲数据保存到db.json文件中用以持久化
//3.发送响应
//怎么改文件里面的数据
//先把文件里的字符串读取出来,转成对象
//然后往对象中push数据
//然后把对象转成字符串
//然后把字符串再次写入文件
//
	Student.save(req.body,function(err){
	if (err){
	return res.status(500).send('Server error')
	}
	res.redirect('/students')
	})
})
router.post('/students/edit',function(req,res){
	
})
module.exports = router

设计操作文件的API

var fs = require('fs')
var dbPath = './db.json'
/**
数据操作文件模块
职责:操作文件中的数据,只处理数据,不关心业务
*/

/**
获取所有学生列表
callback中的参数
	第一个参数是error
		成功是null
		错误是 错误对象
	第二个参数是结果
		成功是数组
		错误是undefined
return[]
*/
exports.find = function(callback){
	fs.readFile(dbPath, 'utf8',function(err,data){	if (err){
	return callback(err)
	}
	callback(null,JSON.parse(data).students)
	})
}
/**
添加保存学生
*/
exports.save = function(student, callback){
	fs.readFile(dbPath,'utf8',function(err,data){
	if (err){
	return callback(err)
	}
	var students = JSON.parse(data).students
	//	处理id唯一的,不重复
	student.id = students[students.length - 1].id + 1
	students.push(student)
	var fileData = JSON.stringify({
	students:students
	})
	fs.writeFile(dbPath, fileData, function(err){
	if (err){
	return callback(err)
	}
	callback(null)
	})
	})
}

/**
删除学生
*/
exports.delete = function(){

}

/**
更新学生
*/
exports.updateById = function(student, callback){
	fs.readFile(dbPath, 'utf8', function(err,data){
	if (err){
	return callback(err)
	}
	var students = JSON.parse(data).students
	//你要修改谁就要先把谁找出来
	//EcmaScript 6 中的一个数组方法:find
	//需要接收一个函数作为参数
	//当某个遍历项符合 item.id === student.id 条件的时候,find会终止遍历,同时返回遍历项
	var stu = students.find(function(item){
	return item.id === student.id
	})
	for(var key in student){
	stu[key] = student[key]
	}
		var fileData = JSON.stringify({
	students:students
	})
	fs.writeFile(dbPath, fileData, function(err){
	if (err){
	return callback(err)
	}
	callback(null)
	})
	})
}

4.11 封装异步API

function fn(callback){
//相当于有
	//var callback = data
	setTimeout(function(){
	var data = 'hello'
	callback(data)
	}, 1000)
	//var data = hello 
	//return data
}
//调用fn,得到内部的data
//因为是异步的,程序不会等待fn()执行结束就会执行后面的代码
//凡是要得到一个函数中异步操作结果,则必须通过回调函数来获取
fn(function(data){
	console.log(data)
})

如何理解回调函数
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值