node.js学习笔记

为期一个半月的学习成果,记录的一些笔记

Day1

Node.js是什么

1.Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine.

node.js是一个js运行环境
node.js可以解释和执行js代码
浏览器中的JavaScript分为3部分:

1)EcmaScript(基本的语法,如if、var、function等)

2)BOM

3)DOM

node.js中的JavaScript:

1)EcmaScript

2)为JavaScript提供了一些服务器级别的操作API(文件读写、网络通信、http服务器等)

2.Node.js uses an event-driven,non-blocking I/O model that makes it lightweight and efficient

关键字:事件驱动,NIO,轻量高效

3.Node.js’s package ecosystem,npm,is the largest ecosystem of open source libraries in the world

拥有包的生态系统,npm,类似于java后台中使用的maven

Node.js能做什么

  1. Web服务器后台
  2. 命令行工具

Node.js读写文件的操作

var fs = require('fs');
fs.readFile('文件路径',function(error,data){
//error是错误对象,data是读取到的文件的内容
});
fs.writeFile('要写文件到哪个路径','要写的内容',function(error){
//error是错误对象
});

node.js简单的http服务
var http = require('http');
var server = http.createServer();
server.on('request',funciton(request,response){

});
serve.listen(端口号,function(){
//绑定端口号之后的回调
})

引用自定义的js文件模块

现有a.js文件与b.js文件在同一目录下,需要在a中引用b,则在a中写:

var b = require('./b.js');

注意一定要带上路径定位符号./ 不然会会将b.js识别成系统模块而报错;末尾的.js可以省略

需要在a中使用b中的数据,需要将b中的数据使用一个名为exports的参数进行挂载:

在b中:exports.param='hello';

在a中:使用var b = require('./b.js');引入b.js
使用b.param则可以得到hello

同理还可以在b中挂载方法到exports上:

exports.add = function(a,b){ return a+b; }

获取请求方的IP地址和端口号

  1. 引入http模块,在server.on的回调中使用request参数获取请求方的IP地址和端口号
  2. console.log(“请求方的地址是:”+req.socket.remoteAddress+“端口号是:”+req.socket.remotePort);

Content-Type

为了解决响应中文乱码的问题,课程中简单介绍了一下content-type

输出之前设置字符集编码utf-8

res.setHeader('Content-type','text/plain;charset=utf-8');

关于content-type的详细类型可参考http://www.runoob.com/http/http-content-type.html


示例:使用'text/plain'的类型,res.end('<p>hello node</p>'),会在页面上输出<p>hello node</p>
使用'text/html'的类型,res.end('<p>hello node</p>'),会在页面上输出hello node
(不设置content-type时,浏览器按照text/html对输出进行解析


Day2

Js代码中的分号问题

js代码中的分号一般都可以省略,除了以下情况:

当一行代码是

以[开头的、

以(开头的、

以`开头的

使用省略分号的书写风格时,建议在上述三种情况下,代码开头加一个分号,示例:

;['苹果','橘子','香蕉'].forEach(function(item){console.log(item)})<br>

初步实现apache的功能

实现将一个服务端文件夹中的所有文件的文件名,以表格的形式展示在页面上

由一个node.js文件和一个html文件实现,两个文件放在同一文件夹下,html页面放一个占位符号,node读取html中的页面字符串、文件夹中的文件名,使用文件名数组拼接成html代码替换占位符,输出合成处理后的页面:

node.js文件

var fs = require('fs')
var http = require('http')
 
var server = http.createServer();
 
server.on('request',function(req,res){
    //文件夹路径
    var basePath = 'D:/workspace/nodetest'
    var files = []
     
    var mainHtml = ''
    var contentStr = ''
     
    fs.readdir(basePath,function(err,data){
        if(err){
            console.log('文件夹不存在')
        }else{
             
            files = data
            files.forEach(function(item){
//循环拼接表格中的html代码
                contentStr += '<tr><td><a href="#">'+item+'</a></td></tr>'
            })
             
            fs.readFile('./demo.html',function(err,data){
                mainHtml = data.toString()
                res.setHeader('Content-Type','text/html;charset=utf-8')
                mainHtml = mainHtml.replace('{{}}',contentStr)
                res.end(mainHtml)
            })
         
        }
         
         
    })
     
})
 
server.listen('3000',function(){
    console.log('服务器在3000端口启动了')
})

用来做页面模板的demo.html文件

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
 
<body>
    <h1>Demo</h1>
    <table>{{}}</table>
</body>
 
</html>

`的使用(键盘上esc下方那个按键)

`是ECMAScript6中的语法,与’的区别
var res = '123
456
789
'
console.log(res)

结果输出123456789

var res = `123
456
789`
console.log(res)

结果输出`123

456

789`


,``中可以直接渲染模板,如:

var content = ''
;['苹果','橘子','香蕉'].forEach(function(item){
content += `
<a>${item}</a>
`
})
console.log(content)

结果为:

<a>苹果</a>
<a>橘子</a>
<a>香蕉</a>

模板引擎art-template在html中的用法

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
 
<body>
<!--引入art-template的相关js文件 -->
    <script src="node_modules/art-template/lib/template-web.js"></script>
     
    <script type="text/template" id="tp1">
        hello {{name}}
    </script>
     
    <script>
        var para = template('tp1',{
            name:'Jack'
        })
        console.log(para)
    </script>
</body>
</html>

在node中使用模板引擎art-template

  1. 安装:npm install art-template
  2. 在需要使用的文档中加载art-template:
    require(‘art-template’)
  3. 使用render函数进行渲染

实例:

var template = require('art-template')
 
var ret = template.render('hello{{name}}',{
    name:'Jack Ma'
})
 
var ret1 = template.render('hello{{each files}}文件有:{{$value}}{{/each}}',{
    files:['Jack Ma','Chen','Wang']
})
 
console.log(ret) //helloJack Ma
console.log(ret1) //hello文件有:Jack Ma文件有:Chen文件有:Wang

服务端渲染和客户端渲染的区别

服务端渲染(同步,在后台使用模板引擎):可以被爬虫抓取到,可以进行SEO

客户端渲染(异步):难以被爬虫抓取到;不利于SEO搜索引擎优化
如:京东的商品列表,为了SEO采用的服务端渲染
京东的评论列表为了用户体验,而不需要SEO,采用的客户端渲染

处理网站中的静态资源

html页面引入静态资源,如:

<link rel="stylesheet" href="/public/css/main.css" >`
<script type="text/javascript" src="/public/js/main.js">

href和src中直接写文件的相对路径如./css/main.css是访问不到的

正确的写法示例:

node.js文件:

var http = require('http')
var fs = require('fs')

http
.createServer(function(req,res){
    var url = req.url
	if(url === '/'){
		fs.readFile('./views/index.html',function(err,data){
			if(err){
				res.end('404 Not Found')
			}else{
				res.setHeader('Content-Type','text/html;charset=utf-8')
				res.end(data)
			}
		})
	}else if(url.indexOf('/public/')===0||url.indexOf('/views/')===0){
		fs.readFile('.'+url,function(err,data){
			if(err){
				res.end('404 Not Found')
			}else{
				res.end(data)
			}
		})
	}
})
.listen('3000',function(){
  console.log('running');
})

主要关注else if这块的写法,每个静态资源的加载都会重新向服务器发送一次新的请求,对每一次请求都要进行处理,示例中的写法将项目中的public文件夹和views文件夹中的文件变成可被请求访问到的

在html页面中写srchref写成/public/css/main.css(以/public开头),就可以了

注意/不可省略,在这里是url根路径的意思

url.parse的用法

了解此方法,有助于进行请求的处理

var url = require('url')

var parseObj = url.parse('127.0.0.1:8888/index?name=张三&gender=male')
//parseObj的值为
{
  protocol: '127.0.0.1:',
  slashes: null,
  auth: null,
  host: '8888',
  port: null,
  hostname: '8888',
  hash: null,
  search: '?name=张三&gender=male',
  query: 'name=张三&gender=male',
  pathname: '/index',
  path: '/index?name=张三&gender=male',
  href: '127.0.0.1:8888/index?name=张三&gender=male' 
}
var url = require('url',true)

var parseObj = url.parse('127.0.0.1:8888/index?name=张三&gender=male')
//parseObj的值为
{
  protocol: '127.0.0.1:',
  slashes: null,
  auth: null,
  host: '8888',
  port: null,
  hostname: '8888',
  hash: null,
  search: '?name=张三&gender=male',
  query: { name: '张三', gender: 'male' },
  pathname: '/index',
  path: '/index?name=张三&gender=male',
  href: '127.0.0.1:8888/index?name=张三&gender=male' 
}

该方法加上第二个参数true时,返回值中的query会被解析成json格式

url.parse得到parseObj对象,parseObj.pathname为请求路径,parseObj.query为url中带的参数

如何通过服务器让客户端重定向

  1. 状态码设置为 302 临时重定向

    res.statusCode=302
  2. 在响应头中通过Location告诉客户端往哪重定向

    res.setHeader(‘Location’,‘要重定向的路径’)

    如果客户端收到的响应状态码是302,就会自动去响应头中找Location,然后对该地址发起新的请求

Day3

各种each

1. art-template中的each

{{each 数组}}
    {{$value}}
{{each}}

2. jQuery中的each

$.each(数组,function(index,item){})
$('div').each(function)

一般用于jQuery选择器选择到的伪数组实例对象

3. forEach

array.forEach(function(item,index){})

是js原生的遍历方法,是EcmaScript5中的一个数组遍历函数,不支持ie8

301状态码和302状态码

  • 301是永久重定向:客户端访问a,被重定向到b,之后再请求访问,不会再经过a,而是直接访问b(浏览器缓存)
  • 302是临时重定向:客户端访问a,被重定向到b,之后再请求访问,还是先经过a,再被重定向到b

CommonJS模块规范

模块引用、模块定义和模块标识三部分


在Node中的JavaScript还有一个很重要的概念:模块系统

  • 模块作用域
  • 使用require方法来导入模块
  • 使用exports接口对象来导出模块中的成员

导出多个成员

 exports.a=‘hello’

 exports.b=function(){}

导出单个成员

 module.exports=‘hello’

exports原理解析

b.js文件被导入

  • 默认有一个module对象:
module=
{
    exports:{}
}
  • require(’./b.js’)默认返回值是module.exports对象

  • 默认exports=module.exports,所以exports.amodule.exports.a等效

    因此exports.a='123’会导致:

exports={a:'123'}
module={
    exports:{
        a:'123'
    }
}

但是如果直接使用exports='123'就会改变exports的指向(直接对module.exports赋值也同样会破坏两者之间的等效的关系),不再与module.exports指向同一个地址,再对exports进行赋值操作都不会影响返回结果

模块加载规则

  1. 优先从缓存中加载

如果main.js中

requrie('./a.js')
requrie('./b.js')

a.js中

console.log('a.js被加载了')
requrie('./b.js')

b.js中

console.log('b.js被加载了')

那么运行main.js,结果为

a.js被加载了

b.js被加载了

b.js只会被加载一次main.js中对b.js的引用是直接从缓存中去读取
2. 自定义模块

 以路径的形式引用
3. 核心模块

 被编译成了二进制文件放在了lib中,直接require(‘包名’)进行引用
4. 第三方模块

 也是使用require(‘包名’)的形式进行引用

 加载过程:

1)先找到当前文件所处目录中的node_modules目录

2)node_modules/第三方模块名/package.json文件

3)node_modules/第三方模块名/package.json文件中的main属性

4)main属性记录了该模块的入口模块

5)最终加载到模块(如果main中的属性值为空,则默认去加载package.json同级的index.js文件)

如果按照上述步骤没有加载到,则去上一级目录下的node_modules目录中去查找;若上级也没有找到,则去上上级目录下的node_modules目录去查找,如此循环,直至当前磁盘根目录

package.json

包描述文件

  • 使用npm init指令,并按照指令提示输入对应参数后可以在当前目录下生成一个package.json文件,该文件记录了一些项目的基本信息:如项目名、版本号、项目描述、项目入口等

  • 在使用npm指令安装第三方包时,加上在包名前/后加上--save,在下载第三方包的同时会将该包的信息添加到package.jsondependencies
  • 使用npm install会根据package.json中的dependencies中的信息下载对应的依赖包

npm常用指令

npm install


安装所有package.json中dependencies下的包


npm install 包名


只下载,不在dependencies中添加依赖


npm install 包名 -save


下载并保存依赖信息


npm uninstall 包名


只删除包的物理文件,不在dependencies中删除依赖


npm uninstall 包名 --save
删除包的物理文件,同时删除dependencies中的依赖


npm config list


查看npm配置信息

使用淘宝镜像

1.安装淘宝镜像

npm install --global cnpm

--global表示安装到全局而非当前目录
2.使用淘宝镜像

安装之后使用cnpm install 包名下载包

3.若想免安装直接使用,可以每次下载时使用:

npm install 包名-register=https://register.npm.taobao.org

或者通过

npm config set register https://register.npm.taobao.org

修改register的地址,以后直接使用npm默认就是使用淘宝镜像了

文件操作路径和模块标识路径问题

  • 文件操作时的相对路径标识./可以省略
  • 加载模块时,相对路径中的./标识不能省略

Day4

Express

express的安装

npm install express

express的helloworld
var express = require('express')
var app = express()
app.get('/',function(req,res){
    res.send('hello express')
})
app.listen('3000',function(){
    console.log('app在300端口启动了')
})
express开放静态资源访问
var express = require('express')
var app = express()
app.use('/public/',express.static('./public/'))
//public下的文件可以被直接访问到了
//use方法的第一个参数可以省略,省略时效果与第一个参数为'/'效果相同

修改完代码自动重启

使用第三方工具nodemon

  1. 安装npm install --global nodemon
  2. 使用nodemon 文件名启动

在Express中使用art-template

  1. 安装

    npm install express-art-template
  2. 引用

    var express = requires(‘express’)

    var app = express()

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

    该方法的第一个参数表示要渲染的页面的后缀
  3. 渲染

    app.render(‘index.html’,{name:‘jack’,gender:‘male’})

    express-art-template会默认去渲染views目录下的文件,render方法的第一个参数为views下的文件名(可以通过app.set('views',指定其他路径)来修改)

使用post进行表单提交

需要使用第三方插件body-parser

1.安装npm install body-parser

官方示例

var express = require('express')
var bodyParser = require('body-parser')

var app = express()

// create application/json parser
var jsonParser = bodyParser.json()

// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })

// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
  if (!req.body) return res.sendStatus(400)
  res.send('welcome, ' + req.body.username)
})

// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
  if (!req.body) return res.sendStatus(400)
  // create user in req.body
})

使用了插件之后,req.body和使用get提交时的req.query是相同的效果

提取路由模块

项目中一般专门使用一个router.js文件来作为路由模块

项目启动的入口还是app.js:

var express = require('express')

var app = express()

var bodyParser = require('body-parser')

var router = require('./router')

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

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

//将router挂载到app上
app.use(router)

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

路由router.js

var express = require('express')

//创建一个路由容器
var router = express.Router()

//把路由都挂载到路由容器中
router
.get('/student',function(req,res){

})
.get('/student/create',function(req,res){

})
.post('/student/create',function(req,res){

})
.get('/student/update',function(req,res){

})
.post('/student/update',function(req,res){

})
.get('/student/delete',function(req,res){

})


module.exports = router

node中使用回调函数

需求是:先执行异步函数fn1,再执行fn2,fn1的返回值作为fn2的参数。由于fn1是异步的,使用顺序逻辑就不行,因此引入回调函数。

fn2是回调函数,作为参数传入fn1方法中,fn1中部分方法的执行结果作为参数再传到fn2中

node.js中大多数操作如文件读写,都是异步操作的,如

var fs = require('fs')
var fn1 = function(){
    fs.readFile(path,function(err,data){
        var para = data
    })
    return para
}
console.log(fn1())

使用顺序逻辑的写法,打印的结果是undefined

想要正确的获取文件读取结果data的数据,就需要使用回调函数

var fs = require('fs')
var fn1 = function(callback){
    fs.readFile(path,function(err,data){
        callback(data)
    })
}
var fn2 = callback(data){
    console.log(data)
}

这样就能正确的获取到文件中的内容了

Array.find

var para = [
    {'id':1,'name':'jack'},
    {'id':2,'name':'mary'},
    {'id':3,'name':'jerry'}
    ]
var p = para.find(function(item){
    return item.id===2
})
console.log(p)
//{'id':2,'name':'mary'}

Array.findIndex

var para = [
    {'id':1,'name':'jack'},
    {'id':3,'name':'mary'},
    {'id':5,'name':'jerry'}
    ]
var p = para.findIndex(function(item){
    return item.id===5
})
console.log(p)
//2

Array.splice

var para = ['1','3','5']
para.splice(1,2)
console.log(para)
//['1','3']

Day5

package-lock.json文件的作用

保存了node_modules中所有包的信息

可以提升npm install的速度

可以用来锁定版本,重新nmp install时,如果没有package-lock.json文件,package.json中的依赖会被升级

404页面的改写

app.use(function(res,req){
    
})

MongoDB

  1. 安装
  2. 添加环境变量

    在环境变量的path中添加mongoDB安装后的bin目录路径
  3. 启动

    在cmd窗口输入mongod指令进行启动,注意mongodb会将输入mongod指令的目录的根目录下的/data/db作为自己的数据存储目录(如在C:/abc/def下输入mongod,会将C:/data/db作为存储目录)
  4. 连接mongodb

    再打开一个窗口输入mongo
  5. 常用指令

    层次结构:数据库->集合(类似表名)->文档(数据)

    show dbs显示所有数据库

    use 数据库名切换数据库

    db查看当前使用的数据库名称

    db.集合名.insertOne(data)插入数据

    show collections查看当前数据库下所有集合名

    db.集合名.find()查看当前集合下所有数据

在node中操纵MongoDB

使用第三方包mongoose

增删改查的demo

var mongoose = require('mongoose')

var Schema = mongoose.Schema

//1.连接数据库
mongoose.connect('mongodb://localhost/myitem');

//2.设计集合结构(表结构)
var userSchema = new Schema({
	userName:{
		type:String,
		required:true
	},
	password:{
		type:String,
		required:true
	},
	email:{
		type:String
	}
})

//3.将文档结构发布为模型
//这里model方法的第一个参数要写大写单数形式的单词,mongoose会自动将其转成小写复数,作为集合名称
var User = mongoose.model('User',userSchema)

//4.进行增删改查的操作

//新增数据
var item1 = new User({
	userName:'admin',
	password:'123456',
	email:'admin@admin.com'
})

item1.save(function(err,data){
	if(err){
		console.log(err)
	}else{
		console.log('添加成功')
		console.log(data)
	}
	
})

//查询数据
//查询所有
User.find(function(err,data){
	if(err){
		console.log(err)
	}else{
		console.log(data)
	}
})

//按条件查询,第一个参数为查询条件,返回结果为满足条件的数组
User.find({
	userName:'admin'
},function(err,data){
	if(err){
		console.log(err)
	}else{
		console.log(data)
	}
})

//查询一条,返回结果为满足条件的第一条数据
User.findOne({
	userName:'admin'
},function(err,data){
	if(err){
		console.log(err)
	}else{
		console.log(data)
	}
})

//删除,第一个参数为删除条件
User.remove({
	userName:'admin'
},function(err,data){
	if(err){
		console.log(err)
	}else{
		console.log('删除成功')
	}
})

//更新数据
User.findByIdAndUpdate('id',{userName:'admin'},function(err,data){
	if(err){
		console.log(err)
	}else{
		console.log('删除成功')
	}
})

使用Node操纵MySQL

安装npm install mysql
官网demo

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();

Promise

异步编程的传统写法

按顺序读取path1,path2,path3路径下的文件内容

fs.readFile('path1',function(err,data){
    console.log(data)
    fs.readFile('path2',function(err,data){
        console.log(data)    
        fs.readFile('path3',function(err,data){
            console.log(data)
        })
    })
})

为了异步编程中回调嵌套过多的问题,ES6中新增了一个api:Promise

Promise容器,开始状态为pending,执行成功之后变为resolved,执行失败之后变成rejected

pending->resolved
        ->rejected

使用了promise之后的写法,将异步方法放到promise容器中,使用then方法进行调用。

创建容器时的resolve方法就是调用时then方法参数中的第一个函数,reject方法就是调用时then方法参数中的第二个函数。

如果第一个then函数的返回值是一个promise容器,则第二个then函数的第一个参数是返回的promise容器中的resolve方法,第二个参数是返回的promise容器中的reject方法

var fs = require('fs')

var p1 = new Promise(function(resolve,reject){
	fs.readFile('./a.js','utf8',function(err,data){
		if(err){
			reject(err)
		}else{
			resolve(data)
		}
	})
})

var p2 = new Promise(function(resolve,reject){
	fs.readFile('./b.js','utf8',function(err,data){
		if(err){
			reject(err)
		}else{
			resolve(data)
		}
	})
})

var p3 = new Promise(function(resolve,reject){
	fs.readFile('./c.js','utf8',function(err,data){
		if(err){
			reject(err)
		}else{
			resolve(data)
		}
	})
})

p1
	.then(function(data){
		console.log(data)
		return p2
	},function(err){
		console.log(err)
	})
	.then(function(data){
		console.log(data)
		return p3
	},function(err){
		console.log(err)
	})
	.then(function(data){
		console.log(data)
	})

Promise封装readFile的api

var fs = require('fs')

function pReadFile(filePath){
	return new Promise(function(resolve,reject){
		fs.readFile(filePath,'utf8',function(err,data){
			if(err){
				reject(err)
			}else{
				resolve(data)
			}
		})
	})
}

pReadFile('./a.js')
	.then(function(data){
		console.log(data)
		return pReadFile('./b.js')
	})
	.then(function(data){
		console.log(data)
		return pReadFile('./c.js')
	})
	.then(function(data){
		console.log(data)
	})

Promise操纵数据库

完成一个业务场景:在数据库中按条件查询一条记录,若查询到了,则打印"用户已存在",若为查询到,则向数据库中插入一条记录

var mongoose = require('mongoose')

var Schema = mongoose.Schema

mongoose.connect('mongodb://localhost/myitem');

var userSchema = new Schema({
	userName:{
		type:String,
		required:true
	},
	password:{
		type:String,
		required:true
	},
	email:{
		type:String
	}
})

var User = mongoose.model('User',userSchema)

var item1 = new User({
	userName:'admin',
	password:'123456',
	email:'admin@admin.com'
})

//
User.findOne({userName:'admin'})
	.then(function(user){
		if(user){
			console.log('用户已存在')
		}else{
			return item1.save();
		}
	})
	.then(function(ret){
		if(ret){
			console.log('保存成功')
			console.log(ret)
		}
	})

Day6

Node中的非模块成员

除了require、exports等模块相关的api,还有两个特殊成员

  • __dirname动态获取当前文件模块所属目录的绝对路径
  • __filename动态获取当前文件的绝对路径


    如在D:\workspace\nodetest有app.js文件
console.log(__dirname)
console.log(__filename)
//  D:\workspace\nodetest
//  D:\workspace\nodetest\app.js

Node中文件操作时的路径问题

现在在D:\workspace路径下有app.js和index.html两个文件

app.js中的内容为

var fs = require('fs')

fs.readFile('./index.html',function(err,data){
    if(err){
        throw err
    }else{
        console.log(data)
    }
})

在D:\workspace路径下打开dos窗口,输入node app.js,可以正确读取文件内容

但是如果在D盘根目录打开dos窗口,输入node workspace\app.js,执行app.js文件,会在读取文件时因为路径错误进入if(err)的逻辑中

因为相对路径使用的./并不是指当前执行文件所处目录

而是执行node命令所处的终端路径


此时使用__dirname可以解决这个问题,写成

var fs = require('fs')
var path = require('path')

fs.readFile(path.join(__dirname,'./index.html'),function(err,data){
    if(err){
        throw err
    }else{
        console.log(data)
    }
})

path.join用来辅助路径拼接

art-template中的include和extend

express中的session

使用第三方包express-session

  1. 安装

    npm install express-session
  2. 配置(需要在挂载路由之前)
    app.use(session({
       secret: 'keyboard cat',
       resave: false,
       saveUninitialized: true
    }))
    //secret配置加密字符串,它会在原有加密基础上和这个字符串拼接起来去加密
    //saveUninitialized为true时,未使用session也会被分配
    
  3. 使用

    当把这个插件配置好之后,我们就可以通过req.session来访问和设置session成员了

    添加session数据:req.session.foo = ‘bar’

    访问session数据:req.session.foo

默认session数据是内存存储的,服务器一旦重启就会丢失,真正的生产环境中会将session持久化

登录把用户user信息放在req.session中,登出时直接把session中的user置为null

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值