node笔记
1.文件操作
let fs=require("fs")
fs.readFile(path,coding,callback)
fs.writeFile(path,content,callback)
2.http模块
//1.加载http核心模块
let http=require("http")
//2.使用http.createServer()创建一个web服务器
let server=http.createServer()
//3.注册request请求事件
//当客户端请求过来,就会触发request请求事件,然后执行
server.on('request',function(req,res){
//发送内容到客户端
res.end("收到请求")
})
//4.绑定端口号,启动服务器
server.listen(3000,fn)
3.request和response
//response主要用于(向客户端)发送内容
response.write()
response.end()
//导入express模块
response.send()
//使用express-art-template
response.render()
//request
request.url //请求路径
request.socket.remoteAddress //请求地址
request.socket.remotePort //请求端口
4.Other module
//4.1 os模块
os.cpus()//获取CPU信息
os.totalmem()//获取内存信息
//4.2 url模块
//url.parse()添加true,使query变成对象
url.parse(href,true)
//protocol,host,port,hostname,hash,serch,query,pathname,path,href
//4.3 path模块
path.basename() //文件名+拓展名
path.dirname() //获取文件中目录部分
path.extname() //获取拓展名
path.parse() //把路径转换成对象,包含root,dir,base,ext,name
path.join() //拼接路径
path.isAbsolute() //判断是否是绝对路径
//4.4 其他成员
//__dirname,是一个成员,可以用来动态获取当前文件模块所属目录的绝对路径
//__filename,可以用来动态获取当前文件的绝对路径(包含文件名)
5.模块化
//5.1 模块化里面的console.log()会打印
//5.2 moudle.exports导出,require()导入
//5.3 exports默认是一个对象,如果直接使用module.export=....后面会覆盖前面
6.编码问题和解决跨域方法
//编码问题
//1.response.write(<header><meta charset='utf-8'></header>)
//2.response.setHeader('Content-Type','text/plan;charset=utf-8')
//解决跨域问题
responese.setHeader('Access-Control-Allow-Origin',"*")
//如果客户端发现收到服务器的状态码是302就会自动去响应头中找location
res.statusCode = 302;
res.setHeader('location', '/');
7.使用node创建后端
let http = require('http');
let fs = require('fs');
let server = http.createServer();
//https://tool.oschina.net/commons
server.on('request', function (request, response) {
let url = request.url;
if (url == '/') {
fs.readFile('./data/resource/resource01/index.html', function (err, data) {
if (err) {
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.end('文件读取失败');
}
else {
response.setHeader('Content-Type', 'text/html; charset=utf-8');
response.end(data);
}
})
}
// application/x-img
else if (url === '/img') {
fs.readFile('./data/resource/resource01/ab2.jpg', function (err, data) {
if (err) {
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.end('文件读取失败');
}
else {
// data 默认是二进制数据,可以通过.toString()转成字符串
//res.end()支持两种数据类型,一种是二进制,另一种是字符串
//图片不需要指定编码,我们常说的编码一般指字符编码
response.setHeader('Content-Type', 'image/jpeg');
response.end(data);
}
})
}
});
server.listen(3000, function () {
console.log('服务器启动成功');
})
8.模板引擎art-template
let fs = require('fs');
let template = require('art-template');
fs.readFile('./12.tpl.htm', function (err, data) {
if (err) {
return console.log('文件读取失败');
}
// data默认是二进制数据,把 data 二进制数据转为 字符串 才可以给模板引擎使用
var ret = template.render(data.toString(), {
name: 'Jack',
age: 18,
province: '北京市',
hobbies: [
'写代码',
'唱歌',
'打游戏'
],
title: '个人信息'
});
console.log(ret);
})
9.express基本使用
//1.引包
let express=require("express")
//2.创建服务器应用程序
let app=express()
//公开指定目录
app.use('/public/',express.static('./'))
//3.接收请求
//可以直接得到路径,有utf-8编码
app.get("/about",fn)
//4.监听端口
app.listen(port,fn)
10.express art-template
const express = require('express')
const app = express()
const port = 3000
app.engine('html', require('express-art-template'));
//express为Response相应对象提供了一个方法:render
//render()默认是不可以使用的,但是如果配置了模板引擎就可以使用了
//res.render('html模板名',{模板数据})
//第一个参数不能写路径,默认会去项目中的views目录查找该模板文件
//Express有一个约定:开发人员把所有的视图文件都放到views目录
app.get('/', (req,res) => {
res.render('404.html')
})
app.listen(port, () => console.log(`Example app listening on port port!`))
//注: 如果希望修改默认的views视图渲染存储目录,可以:
// app.set('views',目录路径);
11.express实例
const express = require('express')
const app = express()
const port = 3000
var comments = [
{
name: 'jack',
message: 'It is a nice day today',
dataTime: '2021.4.20'
},
{
name: 'jon',
message: 'I know',
dataTime: '2021.4.20'
},
];
//放出静态资源
app.use('/public/', express.static('./public/'))
//配置模板引擎
app.engine('html', require('express-art-template'));
app.get('/', (req, res) => {
res.render('index.html', {
comments
})
})
app.get('/post', (req, res) => {
res.render('post.html')
});
app.get('/pinglun', (req, res) => {
// 获取时间
let now = new Date();
let y = now.getFullYear();
let m = now.getMonth() + 1;
let d = now.getDate();
let obj = {
name: req.query.name,
message: req.query.message,
dataTime: (y + '.' + m + '.' + d).toString()
}
// console.log( req.query );
comments.unshift(obj);
res.redirect('/');
});
app.listen(port, () => console.log(`Example app listening on port port!`))
12.express获取POST表单数据
//1.加载模块
const bodyParser=require('body-parser')
//2.通过body-parser获取表单post请求数据
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json)
app.post(url,function(){
app.body
})
13.实例
app.js
/**
* app.js 入门模块
* 职责:
* 创建服务
* 做一些服务相关配置
* 模板引擎
* body-parser 解析表单 post 请求体
* 提供静态资源服务
* 挂载路由
* 监听端口启动服务
*/
const express = require('express');
const router = require('./23.router');
const bodyParser=require('body-parser')
const app = express()
const port = 3000
//放出静态资源
app.use('/node_modules/', express.static('./node_modules'));
app.use('/public', express.static('./public'));
app.engine('html', require('express-art-template'));
// 配置模板引擎bodyParser
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// 把路由容器挂载到APP服务中
app.use(router)
app.listen(port, () => console.log(`Example app listening on port port!`))
router.js
/**
* router.js 路由模块
* 职责:
* 处理路由
* 根据不同的请求方法+请求路径设置具体的请求处理函数
* 模块职责要单一,不要乱写
* 我们划分模块的目的就是为了增强项目代码的可维护性
* 提升开发效率
*/
const fs = require('fs')
const express = require('express');
let asyncAPI = require('./23.asyncAPI')
let dbjson;
// 1.创建一个路由容器
let router = express.Router()
// 2. 把路由都挂载到 router 路由容器中
router.get('/', (req, res) => {
asyncAPI.select(function (err, data) {
if (err) {
return res.status(500).send('server error')
}
dbjson = data
res.render('curdIndex.html', {
fruits: ['苹果', '香蕉', '橙子'],
student: dbjson.Students,
});
})
})
router.get('/students', (req, res) => {
asyncAPI.select(function (err, data) {
if (err) {
return res.status(500).send('server error')
}
dbjson = data
res.render('curdIndex.html', {
fruits: ['苹果', '香蕉', '橙子'],
student: dbjson.Students,
});
})
})
router.get('/students/new', (req, res) => {
// 1.获取表单数据
// 2.处理
// 将数据保存到db.json文件中持久化
// 3.发送响应
res.render('new.html')
})
router.post('/students/new', (req, res) => {
asyncAPI.add(req.body, function (err) {
if (err) {
return res.status(500).send('server error')
}
res.redirect('/students')
})
})
router.get('/students/edit', (req, res) => {
// console.log(req.query.id);
// 根据id获取db.json
asyncAPI.getById(req.query.id, function (err, data) {
if (err) {
return res.status(500).send('server error')
}
// console.log(data);
res.render('edit.html', {
student: data
})
})
})
router.post('/students/edit', (req, res) => {
// console.log("h");
console.log(req.body);
asyncAPI.update(req.body, function (err) {
if (err) {
return res.status(500).send('server error')
}
res.redirect('/students')
})
})
router.get('/students/delete', (req, res) => {
// console.log(req.query);
asyncAPI.delete(req.query.id, function (err) {
if (err) {
return res.status(500).send('server error')
}
})
res.redirect('/students')
})
// 3.导出路由
module.exports = router
asyncAPI.js
/**
* student.js
* 数据操作文件模块
* 职责:操作文件中的数据,只处理数据,不关心业务
*
* 这里才是我们学习 Node 的精华部分:奥义之所在
* 封装异步 API
*/
let fs = require('fs')
let jsonPath = './db.json'
exports.select = function (callback) {
fs.readFile(jsonPath, 'utf8', function (err, data) {
if (err) {
//+callback 防止传参传不出来
return callback(err)
}
callback(null, JSON.parse(data))
})
}
exports.add = function (obj, callback) {
fs.readFile(jsonPath, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
// 转换成对象
let Students = JSON.parse(data).Students;
obj.id = Number.parseInt(Students[Students.length - 1].id) + 1
// 添加对象
Students.push(obj)
//将对象转换成字符串
var fileData = JSON.stringify({
Students
})
fs.writeFile(jsonPath, fileData, function (err) {
if (err) {
return callback(err)
}
callback(null)
})
})
}
exports.update = function (body, callback) {
//查询找到数组
// 根据id修改值
// 写入db.json
fs.readFile(jsonPath, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
// console.log(JSON.parse(data));
let Students = JSON.parse(data).Students
// console.log(typeof body.id,typeof Student[1].id);
for (let i = 0; i < Students.length; i++) {
if (body.id == Students[i].id) {
Students[i] = body
}
}
// 将对象转换成字符串
let fileData = JSON.stringify({
Students
})
fs.writeFile(jsonPath, fileData, function (err) {
if (err) {
return callback(err)
}
callback(null)
})
})
}
exports.delete = function (id, callback) {
//根据id查询数据
//转换成数组,splice()
// 写入文件
fs.readFile(jsonPath, 'utf8', function (err, data) {
if (err) {
return callback(err)
}
let Students = JSON.parse(data).Students
for (let i = 0; i < Students.length; i++) {
if (Number.parseInt(Students[i].id) === Number(id)) {
Students.splice(i, 1)
}
}
// console.log( Students);
let fileData = JSON.stringify({
Students
})
fs.writeFile(jsonPath, fileData, function (err) {
if (err) {
return callback(err)
}
callback(null)
})
})
}
//获取id
exports.getById = function (id, callback) {
fs.readFile(jsonPath, 'utf8', function (err, data) {
let res = [];
if (err) {
return callback(err)
}
let arr = JSON.parse(data).Students
for (let i = 0; i < arr.length; i++) {
if (Number.parseInt(arr[i].id) === Number(id)) {
res = arr[i];
}
}
callback(null, res)
})
}
14.MongoDB基本操作
-
npm install mongoose -S
-
mongod启动数据库
-
mongo连接数据库
14.1 增
//1.加载模块 let mongoose=require("mongoose") //2.连接数据库 // 指定连接的数据库不需要存在,当你插入第一条数据后就会自动被创建出来 mongoose.connect('mongodb://localhost/tableName') //3.设计表结构 // 字段名称就是表结构中的属性名称 // 约束的目的是为了保证数据的完整性 let Schema=mongoose.Schema let userSchema=new Schema({ username: { type: String, required: true //必须有 }, password: { type: String, required: true }, email: { type: String } }) // 4.将文档架构发布为模型 // mongoose.model()就是用来讲一个架构发布为model // 第一个参数:传入一个大写名词单数字符串来表示你的表名称 // mongoose 会自动将大写名词的字符串生成小写复数的集合名称 // 例如,这里的User最终会变成user集合名称,这里的返回值是一个模型构造函数 let User=mongoose.model('User',userSchema) //5.保存 var admin=new User({ username: "黑漆漆", password: "123456", email: "admin@qq.com" }) admin.save(function (err, ret) { if (err) { console.log("error") } else { console.log(ret) } })14.2 删
let mongoose=require('mongoose') mongoo.connect('mongodb://localhost/tableName') let Schema=mongoose.Schema let userSchema=new Schema({ username:{ type:String, required:true }, password:{ type:String, required:true }, email:{ type:String } }) let User=mongoose.model('User',userSchema) User.remove({ username:'name' },fn(err,res))14.3 改
let mongoose=require('mongoose') mongoose.connect('mongodb://localhost/tableName') let Schemm=mongoose.Schema let userSchema=new Schemm({ username:{ type:String, require:true }, password:{ type:String, require:true }, email:{ type:String } }) let user=mongoose.model('User',userSchema) user.findByIdAndUpdate('608c05ca79d0220c0c3e0e0b',{ password:'123' },fn(err,res))14.4 查
let mongoose = require('mongoose') // 表结构 let Schema = mongoose.Schema mongoose.connect('mongodb://localhost/itcast') var userSchema = new Schema({ username: { type: String, required: true //必须有 }, password: { type: String, required: true }, email: { type: String } }) let User = mongoose.model('User', userSchema) //查询 // 第一个参数为对象(查询条件),可选 // User.find({ // username: "陈平安" // }, function (err, ret) { // if (err) { // console.log(err) // } // else { // console.log(ret) // } // }) // 按条件查询单个 User.findOne({ username: "陈平安" }, function (err, ret) { if (err) { console.log(err) } else { console.log(ret) } })
15.实例
app.js
/**
* app.js 入门模块
* 职责:
* 创建服务
* 做一些服务相关配置
* 模板引擎
* body-parser 解析表单 post 请求体
* 提供静态资源服务
* 挂载路由
* 监听端口启动服务
*/
const express = require('express');
const router = require('./31.router');
const bodyParser = require('body-parser')
const app = express()
const port = 3000
//放出静态资源
app.use('/node_modules/', express.static('./node_modules'));
app.use('/public', express.static('./public'));
app.engine('html', require('express-art-template'));
// 配置模板引擎bodyParser
// 通过body-parser获取表单post请求数据
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// 把路由容器挂载到APP服务中
app.use(router)
app.listen(port, () => console.log(`Example app listening on port port!`))
router.js
/**
* router.js 路由模块
* 职责:
* 处理路由
* 根据不同的请求方法+请求路径设置具体的请求处理函数
* 模块职责要单一,不要乱写
* 我们划分模块的目的就是为了增强项目代码的可维护性
* 提升开发效率
*/
const fs = require('fs')
const express = require('express');
let asyncAPI = require('./31.mongoo')
// 1.创建一个路由容器
let router = express.Router()
// 2. 把路由都挂载到 router 路由容器中
router.get('/', (req, res) => {
asyncAPI.find(function (err, data) {
if (err) {
return res.status(500).send('server error')
}
res.render('McurdIndex.html', {
fruits: ['苹果', '香蕉', '橙子'],
student: data,
});
// console.log(data[0]._id,typeof data[0]._id)
})
})
router.get('/students', (req, res) => {
asyncAPI.find(function (err, data) {
if (err) {
return res.status(500).send('server error')
}
res.render('McurdIndex.html', {
fruits: ['苹果', '香蕉', '橙子'],
student: data,
});
})
})
router.get('/students/new', (req, res) => {
// 1.获取表单数据
// 2.处理
// 将数据保存到db.json文件中持久化
// 3.发送响应
res.render('Mnew.html')
})
router.post('/students/new', (req, res) => {
var saveData = new asyncAPI(req.body)
saveData.save(function (err) {
if (err) {
return res.status(500).send("server error")
}
res.redirect('/students')
})
})
router.get('/students/edit', (req, res) => {
req.query.id = req.query.id.replace(/"/g, "")
// console.log(req.query.id, typeof req.query.id)
asyncAPI.findById(req.query.id, function (err, data) {
if (err) {
return res.status(500).send('server error')
}
res.render('Medit.html', {
student: data
})
})
})
router.post('/students/edit', (req, res) => {
// console.log(req.body.id, typeof req.body.id)
let id = req.body.id.replace(/"/g, "")
asyncAPI.findByIdAndUpdate(id, req.body, function (err) {
if (err) {
return res.status(500).send('server error')
}
res.redirect('/students')
})
})
router.get('/students/delete', (req, res) => {
let id = req.query.id.replace(/"/g, "")
// console.log(id,typeof id)
asyncAPI.remove({
_id: id
}, function (err) {
if (err) {
return res.status(500).send('server error')
}
})
res.redirect('/students')
})
// 3.导出路由
module.exports = router
mongodb.js
let mongoose = require('mongoose')
//1.连接数据库
mongoose.connect('mongodb://localhost/itcast')
// 2.设计表结构
let Schema = mongoose.Schema
let studentSchema = new Schema({
name: {
type: String,
required: true
},
gender: {
type: Number,
enum: [1, 2],
default: 1
},
age: {
type: Number
},
hobbies: {
type: String
}
})
// 直接导出模型构造函数
module.exports = mongoose.model("newBody", studentSchema)
16.实例
app.js
let express = require("express")
let path = require("path")
let router = require('./33.router')
let bodyParser = require("body-parser")
let session = require('express-session')
let app = express()
// 释放静态资源
app.use('/public/', express.static(path.join(__dirname, "./public/")))
app.use('/node_modules/', express.static(path.join(__dirname, "./node_modules")))
app.engine('html', require("express-art-template"))
// 设置资源目录,默认就是 views
app.set('views', path.join(__dirname, './views/'))
// 配置解析表单请求体
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// express-session
app.use(session({
// 配置加密字符串,他会在原有加密基础上和这个字符串拼接起来去加密
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
app.use(router)
app.listen(3000, function () {
console.log("running")
})
router.js
let express = require('express')
let router = express.Router()
let user = require('./models/user')
let md5 = require('blueimp-md5')
router.get('/', function (req, res) {
// console.log(req.session.user, typeof req.session.user)
res.render('NewIndex.html', {
user: req.session.user
})
})
router.get('/login', function (req, res) {
res.render('login.html')
})
router.post('/login', function (req, res) {
// console.log(req.body)
req.body.password = md5(md5(req.body.password))
user.find({
"email": req.body.email,
"password": req.body.password
}, function (err, data) {
if (err) {
return res.status(500).json({
err_code: 500,
message: "server error"
})
}
if (data.length == 0) {
return res.status(200).json({
err_code: 1,
message: "not found"
})
}
// 登录成功使用session记录登录状态
req.session.user = data
// console.log(data.nickname)
res.status(200).json({
err_code: 0,
message: "OK"
})
// console.log(data)
})
})
router.get('/register', function (req, res) {
res.render('register.html')
})
router.post('/register', function (req, res) {
// console.log(req.body.email)
user.find({
email: req.body.email
}, function (err, data) {
if (err) {
// express提供了一个响应方法 json
// 该方法接收一个对象作为参数,会将对象转换成字符串
return res.status(500).json({
success: false,
message: 'server error'
})
}
if (data.length !== 0) {
// console.log(data)
return res.status(200).json({
success: false,
message: '邮箱已存在'
})
}
// 对密码进行md5重复加密
req.body.password = md5(md5(req.body.password))
new user(req.body).save(function (err, data) {
if (err) {
return res.status(500).json({
success: false,
message: 'server error'
})
}
// 注册成功使用session记录用户的登录状态
req.session.user = data
res.status(200).json({
success: true,
message: 'OK'
})
// 服务端重定向只针对同步请求有效,异步请求无效
// res.redirect('/')
})
})
})
router.get('/topics/new', function (req, res) {
res.render('topic/new.html')
})
router.get('/logout', function (req, res) {
req.session.user = ''
res.redirect('/')
})
module.exports = router
user.js
var mongoose = require('mongoose')
// 连接数据库
mongoose.connect('mongodb://localhost/test')
var Schema = mongoose.Schema
var userSchema = new Schema({
email: {
type: String,
required: true
},
nickname: {
type: String,
required: true
},
password: {
type: String,
required: true
},
created_time: {
type: Date,
// 注意:这里不要写 Date.now() 因为会即刻调用
// 这里直接给了一个方法:Date.now
// 当你去 new Model 的时候,如果你没有传递 create_time ,则 mongoose 就会调用 default 指定的Date.now 方法,使用其返回值作为默认值
default: Date.now
},
last_modified_time: {
type: Date,
default: Date.now
},
avatar: {
type: String,
default: '/public/img/avatar-default.png'
},
bio: {
type: String,
default: ''
},
gender: {
type: Number,
enum: [-1, 0, 1],
default: -1
},
birthday: {
type: Date
},
status: {
type: Number,
// 0 没有权限限制
// 1 不可以评论
// 2 不可以登录
enum: [0, 1, 2],
default: 0
}
})
module.exports = mongoose.model('User', userSchema)

浙公网安备 33010602011771号