Node.js
node导出exports
- node中时模块作用域,默认文件中所有的成员只在当前文件模块有效
- 对于希望可以被其他模块访问的成员,我们就需要把这些公开的成员都挂载到
exports
接口对象中就可以了
导出多个成员(必须在对象中)
exports.a = 123
exports.b = 'hello'
exports.c = function(){
console.log('ccc')
}
exports.d = {
foo:'bar'
}
//上面导出的是一个对象,{a=123,b='hello'....}
导出单个成员(拿到的就是:函数,字符串)
module.exports = 'hello'
以下情况会覆盖
module.exports = 'hello'
//以这个为准,后面的覆盖前者
module.exports = function(x,y){
return x+y
}
也可以这样来导出多个成员:
module.exports = {
add:function(){
return x+y
},
str:'hello'
}
//OR
module.exports.foo = 'bar'
module.exports.add = function(x,y){
return x+y
}
exports 和module.exports的区别
console.log(exports === module.exports)//结果:true
//两者一致,那就说明,我可以使用任意一方来导出
exports.foo = 'bar'
//等价于
module.exports.foo = 'bar'
exports 是module.exports的一个引用
export.foo = 'bar' //{foo:'bar'}
module.exports.a = 123 //{foo:'bar',a:123}
//exports !== module.exports
//最终return 的是module.exports
//所以无论你exports中的成员是什么都没有用
export = {
a:123
}
//{foo:'haha',a:123}
module.exports.foo = 'haha'
//没关系,混淆你的
exports.c = 456
//重新建立了和module.exports之间的引用关系了
exports = module.exports
//由于在上面建立了引用关系,所以这里是生效的
//{foo:'haha',a:789}
exports.a = 789
//前面再牛逼,这里都全部推翻,重新赋值
//最终得到的是function
module.exports = function(){
console.log('hello')
}
- 如果你实在分不清exports 和 module.exports
- 你可以忘记exports
- 而只是用module.exports也没问题
- module.exports.xxx = xxx
- module.exports = {}
最终return的其实是module.exports
npm
-
npm网站
npmjs.com
-
npm命令行工具
npm的第二层含义就是一个命令行工具,只要你安装了Node就已经安装了npm
npm也有版本这个概念
可以通过在命令行中输入
npm --version
升级npm(自己升级自己)
npm install --global npm
常用命令
-
npm init(生成package.json)
- npm init -y 可以跳过向导,快速生成
-
npm install
- 一次性把dependencies选项中的依赖全部安装
-
npm install 名包
- npm i 包名(简写)
-
npm install --save 报名
- 下载并保存依赖项(package.json文件中的dependencies选项)
- npm i -S 包名(简写)
-
npm uninstall 包名
- 只删除,如果有依赖项依然保存
- npm un 包名(简写)
-
npm uninstall --save 包名
- 删除的同时也会把依赖信息也去除
- npm un -S 包名
-
npm help
- 查看所有命令使用帮助
-
npm 命令 --help
- 查看指定命令的使用帮助
- 例如忘记了uninstall命令的简写了,这个时候,可以输入npm uninstall --help来查看使用帮助
解决npm被墙问题
npm存储包文件的服务器在国外,有时候会被墙,速度很慢,所以我们需要的解决这个问题
http://npm.taobao.org/ 淘宝的开发团队把npm在国内做了一个备份
-
安装淘宝的cnpm
# --global表示安装到全局,而非当前目录 npm install --global cnpm
-
如果不想安装
cnpm
又想使用淘宝的服务器来下载npm install jquery --registry=https://registry.npm.taobao.org
但是每一次手动这样加参数会很麻烦,所以我们吧这个选项加入配置文件中
npm config set registry https://registry.npm.taobao.org
#只要经过了上面命令的配置,则你以后所有的 npm install 都会默认通过淘宝的服务器来下载
#查看npm配置信息npm config list
require方法的加载规则
凡是第三方模块都必须通过npm来下载
使用可通过require('包名')
使用
既不是核心模块,也不是路径形式的模块
先找到当前文件所处的目录中的node_modules目录
再找到包中package.json文件的main属性
main属性中就记录了比如art-template的入口模块
然后加载使用这个第三方包
如果package.json文件不存在或者main指定的入口模块也没有
则node会自动找该目录下的index.js,index.js会作为一个默认备选项
如果以上条件都不成立,则会进入上一级目录中的node_modules目录查找
如果上一级还没有,则继续往上上一级查找
如果直到当前磁盘更目录还找不到,最后报错:
can not find module xxx
path路径操作模块
-
path.basename
- 获取一个路径的文件名(默认包含扩展名)
-
path.dirname
- 获取一个路径中的目录部分
-
path.extname
- 获取一个路径中的扩展名部分
-
path.parse
- 把一个路径转换为对象
- root根路径
- dir目录
- base包含后缀名的文件名
- ext后缀名
- name不含后缀名的文件名
- 把一个路径转换为对象
-
path.join
- 当需要进行路径拼接的时候,推荐使用这个方法
path.isAbsolute判断一个路径是否是绝对路径
node中的文件路径问题
在每个模块中,除了require
、exports
等模块相关api外,还有两个特殊成员:
-
--dirname
可以用来获取当前文件模块所属目录的绝对路径(动态获取) -
--filename
可以用来获取当前文件的绝对路径(动态获取)
在文件操作中,使用相对路径是不可靠的,因为在node中文件操作的路径被设计为相对于执行node命令所处的路径
文件操作路径中,相对路径设计的就是相对与执行node命令所处的路径
所以在操作文件路径时最好用path.join(__dirname,'/xxx.txt')
例:fs.readFile(path.join(__dirname,'./a.txt'),'utf-8',function(err,data){})
require(‘./xx’)模块路径:
模块中的路径标识和文件操作中的相对路径标识不一致
模块中的路径标识就是相对于当前文件模块,不受执行node命令所处路径影响
Express框架
1.起步
安装:
npm install -save express
2.修改完代码自动重启
nodemon是一个基于node.js开发的一个第三方命令行工具,我们使用的时候需要独立安装
#在任意目录执行该命令都可以
#也就是说,所有需要--global来安装的包都可以在任意目录执行
npm install --global nodemon
安装完毕后,使用
node app.js
#使用nodemon
nodemon app.js
只要是通过nodemon app.js
启动的服务,则他会监视你的文件变化,当文件发生变化的时候,自动帮你重启服务器。
3.在Express中配置使用art-template模板引擎
安装:
npm install --save art-template
npm install --save express-art-template
#OR
npm install --save art-template express-art-template
配置:
app.engine('art',require('express-art-template')) //art可以自定义比如写成'html'
使用:
app.get('/',function(req,res){
//express 默认回去项目中的views目录找index.html
//render函数的第一个参数是views文件夹中的页面,第二个参数是页面渲染的数据
res.render('index.html',{
user:{
name:'chc',
age:18
}
})
})
如果希望修改默认的views视图渲染存储目录,可以
//注意,第一个参数views不要写错app.set('views',目录路径)
4. 在express获取表单数据
Express内置了一个API,可以直接通过req.query来获取GET请求的参数
req.query
post请求:
在express中没有内置获取表单POST请求体的API,这里我们需要使用一个第三方包,body-parse
.
安装:
npm install --save body-parser
配置:
配置模板引擎和body-parser一定要在app.use(router)挂载路由之前
var express = require('express')
//引包
var bodyParser = require('body-parser')var app = express()
//配置body-parser
//只要加入这个配置,则在req请求对象上会多出来一个属性:body
//也就是说你就可以直接通过req.body来获取表单POST请求提数据了
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//使用
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})
5.项目router路由模块
router.js页面模块
var express = require('express')
var router = express.Router()
//请求的路由
router.get('/',function(req,res){ })
router.post('/home',function(req,res){ })
//导出routermodule.exports = router
app.js入口文件
//引入文件
var router = require('./router')
//把路由容器挂载到app服务中
app.use(router)
基于原生XMLHttpRequest封装get方法
function get(url,callback){
var oReq = new XMLHttpRequest()
oReq.onload = function(){
callback(oReq.responseText)
}
oReq.open('get',url,true)
oReq.send()}
6.Express-session
安装:
npm install express-session
使用:(路由之前)
var session = require('express-session')
app.use(session({
//配置加密字符串,他会在原有加密基础上和这个字符串拼接起来加密,增加安全性 secret:'xxxxxx',
//自定义的加密字符串 resave:false,
//为true时,删除coolie中的钥匙(token),重新加载后会重新生成新的钥(token)
//为false时,删除后重新加载不在生成,
//只有触发了req.session.xxx='xxx'才会生成saveUninitialized:true}))
往session插值和取值
//插值
router.get('/',function(req,res){
req.session.xxx = 'chc'
})
//取值
console.log(req.session.xxx)
//结果:chc//清除(两种方法)
req.session.xxx = null;
delete req.session.xxx;
中间件
配置一个处理404的中间件(必须放在各中间件的最后面)
app.use(function(req,res){ res.render('404.html')})
配置一个全局错误处理中间件(必须是四个参数)
//被请求触发的中间件,也可以是router.js中的路由事件
app.get('/',function(req,res,next){
fs.readFile('./xxx',function(err,data){
if(err){
//next(err)可以触发错误处理中间件把错误信息err传给它
next(err)
}
})})
app.use(router)
//错误处理中间件
app.use(function(err,req,res,next){
res.status(500).json({
err_code:500,
message:err.message
})})
mongoDB
启动和停止mongoDB
启动:
#mongodb默认使用执行mongod命令所处盘符根目录下的/data/db做为自己的数据存储目录
#所以在第一次执行该命令之前先自己手动建一个/data/dbmongod
如果想要修改默认的数据存储目录,可以:
mongod --dbpath=数据存储目录路径
停止:
在开启服务的控制台,直接Ctrl+c即可停止。
连接和推出数据库
连接:(另外打开cmd)
//该命令默认连接本机的MongoBD服务
mongo
推出:
//在连接状态输入exit推出连接
exit
基本命令
-
show dbs
- 查看显示所有数据库
-
db
- 查看当前操作的数据库
-
use 数据库名称
- 切换到指定的数据(如果没有会新建)
使用第三方mongose插件来管理数据
安装
npm install mongooser
使用
//引入包
var mongoose = require('mongoose')
//连接数据库
var Schema = mongoose.Schemamongoose.connect('mongodb://localhost/xxx数据库名')
//数据约束
var userSchema = new Schema({
username:{
type:String,
required:true
},
password:{
type:String,
required:true
},
email:{
type:String,
required:true
}})
//创建模型
var User = mongoose.model('User',userSchema)
插入数据
//增加数据
var admin = new User({
username:'admin',
password:'233444',
email:'admin@admin.com'
})
//最后保存
admin.save(function(err,ret){
if(err){
console.log('保存失败')
}else{
console.log('保存成功')
console.log(ret)
}})
查询所有:
User.find(function(err,res){})
条件查询
User.findOne({username:'zs'},function(err,res){})
删除:
User.remove({username:"sz"},function(err,res){})
更新数据:
User.findByIdAndUpdate('12',{password:'123'},function(err,res){})
//参数1:数据id,参数2:需要修改的数据
new scheme()
设计数据格式
create_time:{
type:Date,
//注意:这里不要写Date.now()因为会即刻调用
//这里直接给了一个方法:Date.now
default:Date.now
}
使用mysql插件来管理数据
tps:用mysql来管理数据时使用,不是mongoDB
安装
npm install mysql --save
使用
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
connection.end();