# nodejsLearn
**Repository Path**: happydts/nodejsLearn
## Basic Information
- **Project Name**: nodejsLearn
- **Description**: node学习的记录
- **Primary Language**: HTML
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2019-10-12
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# NodeJs 学习
## 常见问题处理
### 解决nodejs被墙问题
- 安装cnpm
```shell
npm install --global cnpm
```
- 使用淘宝镜像
```shell
npm --config registry https://registry.npm.taobao.org
```
- 查看配置
```shell
npm config list
```
### 修改完代码自动重启
`nodemon`来帮我们解决频繁修改代码重启服务器的问题
```shell
npm install --global nodemon
```
- 安装完毕后使
```shell
node app.js
#使用nodemon
nodemon app.js
```
### 修改默认的views路径
```javascript
app.set('views',想要修改的路径)
```
### 表单get提交
- express内置
```javas
var query = req.query
```
### javacript api
#### json文件查找
```java
var ret = students.find(function (item) {
return item.id === parseInt(id)
})
返回一个对象
```
#### json文件查找下标
```javascript
var retId = students.findIndex(function(item){
return item.id === id
})
```
#### json文件删除
```javascript
students.splice(通过查找到的下标,1)
```
#### 封装ajax方法
```javascript
```
### fs.writeFile()
```javascript
// 把字符串保存到文件中
fs.writeFile(dbPath, fileData, function (err) {
if (err) {
// 错误就是把错误对象传递给它
return callback(err)
}
// 成功就没错,所以错误对象是 null
callback(null)
})
```
### 关于url和 Java不同
#### 关于nodeJs
- `href` ,相对路径的话还是会被解析成url地址,把所有的路径都想象成 url 地址, 浏览器在真正发请求的时候会最终把 http://127.0.0.1:3000 拼上


- 在这里写成
```javascript
```
- 两种方式都行,相对路径最终还是会被解析成从服务器根路径开始。。。
- 而`fs.readFile('')`则是读取的文件路径
#### 而对于java
`webapp`中的 `html` 文件请求 `css` 和 `js` 还是用文件路径,但是要放行静态资源
#### json字符串转换对象
```javascript
JSON.stringify({
students:students
})
```
这样的话转出来的就是这样的格式
```json
{
"students":[
{"id":1,"name":"张三三","gender":"0","age":"22","hobbies":"吃饭、睡觉、打豆豆"},
{"id":2,"name":"张三三","gender":"0","age":"22","hobbies":"吃饭、睡觉、打豆豆"},
{"id":3,"name":"张三三","gender":"0","age":"22","hobbies":"吃
]
}
```
```javascript
JSON.stringify(students)
```
而这样的话转出来的就是这样的格式
```json
[
{"id":1,"name":"张三三","gender":"0","age":"22","hobbies":"吃饭、睡觉、打豆豆"},
{"id":2,"name":"张三三","gender":"0","age":"22","hobbies":"吃饭、睡觉、打豆豆"},
{"id":3,"name":"张三三","gender":"0","age":"22","hobbies":"吃
]
```
### 从文件读取的数据一定是字符串,所以一定要手动转换成对象,通过url拿到的也是字符串
## express 整合art-template
[art-template官网](http://aui.github.io/art-template/)
[art-template整合express](http://aui.github.io/art-template/express/)
- 安装
```shell
npm install --save art-template
npm install --save express-art-template
```
- 使用
```java
var express = require('express');
var app = express();
app.engine('art', require('express-art-template'));
app.set('view options', {
debug: process.env.NODE_ENV !== 'production'
});
app.get('/', function (req, res) {
res.render('index.art', {
user: {
name: 'aui',
tags: ['art', 'template', 'nodejs']
}
});
});
```
+ 路径默认在views路径之下
+ res.send()方法默认会设置utf-8编码,最多只能发送字符串,而res.render()可以直接设置views下的页面
## 表单提交 body-parser
### get提交
- 安装
```shell
npm install path
```
- 使用
```javascript
var path = require('path')
var parseobj = path.parse(url,true)
// ? 前面的部分
var pathname = parseobj.pathname
// ? 后面的部分
var query = parseobj.query
```
- express
- ```javascript
req.query
```
-
### post提交
- 安装
```shell
npm install body-parser --save
```
- 使用
```java
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// 配置模板引擎和 body-parser 一定要在 app.use(router) 挂载路由之前
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
//拿取post提交的内容
var obj= req.body
})
```
- body-parser
- ```java
req.body
```
-
## Router路由
- router.js
```javascript
var express = require('express')
var router = express.Router()
/*
* 渲染学生列表页面
*/
router.get('/students', function (req, res) {
res.render('index.html')
})
/*
* 渲染添加学生页面
*/
router.get('/students/new', function (req, res) {
res.render('new.html')
})
/*
* 处理添加学生
*/
router.post('/students/new', function (req, res) {
})
/*
* 渲染编辑学生页面
*/
router.get('/students/edit', function (req, res) {
})
/*
* 处理编辑学生
*/
router.post('/students/edit', function (req, res) {
})
/*
* 处理删除学生
*/
router.get('/students/delete', function (req, res) {
})
// 3. 把 router 导出
module.exports = router
```
- app.js
```javascript
var router = require('./router')
//创建路由
app.use(orouter)
```
## mongod数据库
### 查看数据库版本
```shell
mongod --version
```
### 启动和关闭数据库
第一次需要在启动盘符新建data/db文件夹
```shell
mongod #启动
# crtl+c关闭
```
如果想要更改指定操作文件夹
```shell
mongod --dbpath=数据盘符目录
```
### 连接数据库
```shell
# 该命令默认连接本机的mongo数据库
mongo
```
退出
```shell
exit
```
### 基本命令
+ `show dbs`
+ 查看显示所有数据库
- ` use 数据库名称`
- `db`
- 查看当前使用的数据库
+ show collections
+ 查看当前数据库里的集合
+ 插入数据
+ db.students.insertOne({"name":"youngdeng"}
+ 查找数据
+ db.students.find()
### 在node中使用mogodb
#### 官方模式
[mongodb官方文档](https://www.npmjs.com/package/mongodb)
#### 更便捷的方式
[mongoose](https://mongoosejs.com/)
```shell
npm i mongoose
```
实例
```java
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Cat = mongoose.model('Cat', { name: String });
const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));
```
```javascript
var mongoose = require('mongoose')
// 连接数据库
mongoose.connect('mongodb://localhost/test', { useMongoClient: true })
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)
```
### 查询数据
```javascript
User.findOne({
email: body.email,
password: md5(md5(body.password))
}, function (err, user) {
if (err) {
return res.status(500).json({
err_code: 500,
message: err.message
})
}
// 如果邮箱和密码匹配,则 user 是查询到的用户对象,否则就是 null
if (!user) {
return res.status(200).json({
err_code: 1,
message: 'Email or password is invalid.'
})
}
// 用户存在,登陆成功,通过 Session 记录登陆状态
req.session.user = user
res.status(200).json({
err_code: 0,
message: 'OK'
})
})
```
#### 查询所有
#### 查询单个数据
### 更新数据
```javascript
User.findOne({
$or: [{
email: body.email
},
{
nickname: body.nickname
}
]
}, function (err, data) {
if (err) {
return res.status(500).json({
success: false,
message: '服务端错误'
})
}
// console.log(data)
if (data) {
// 邮箱或者昵称已存在
return res.status(200).json({
err_code: 1,
message: 'Email or nickname aleady exists.'
})
return res.send(`邮箱或者密码已存在,请重试`)
}
// 对密码进行 md5 重复加密
body.password = md5(md5(body.password))
new User(body).save(function (err, user) {
if (err) {
return res.status(500).json({
err_code: 500,
message: 'Internal error.'
})
}
// 注册成功,使用 Session 记录用户的登陆状态
req.session.user = user
// Express 提供了一个响应方法:json
// 该方法接收一个对象作为参数,它会自动帮你把对象转为字符串再发送给浏览器
res.status(200).json({
err_code: 0,
message: 'OK'
})
// 服务端重定向只针对同步请求才有效,异步请求无效
// res.redirect('/')
})
})
```
### 删除数据
## mysql
## path模块
+ path.isAbsolute()
+ 看是不是绝对路径
+ path .basename
+ 获取一个路径的文件名(包含扩展名)
+ path.dirname
+ 获取一个路径的目录部分
+ path.extname
+ 获取扩展名
+ path.join
+ 当你需要路径拼接的时候,推荐使用这个方法
+ path.parse
+ 把一个路径转换成对象
+ root根路径
+ dir目录
+ base包含后缀名的文件名
+ ext后缀名
+ name不包含后缀名的文件名
+
#### __dirname(文件所在位置)
```javascript
app.use('/public/', express.static(path.join(__dirname, './public/')))
```
#### ——filename(文件所在位置精确到文件)
## 中间件
和拦截器差不多
### 配置404的中间件(在路由之后)
```javascript
app.use(function(req,res){
res.render('404.html')
})
```
### 配置一个全局错误处理(在路由之后)
```javascript
if(err){
//直接找有四个参数的
next(err)
}
//要写全参数,必须写四个
app.use(function(err,req,res,next){
// console.log('error')
res.send(500).send(err.message)
})
```