node20180927

1. fs读文件、写文件

// 1 fs读文件
var fs = require('fs')
fs.readFile('./20180926 demo/a.text', function (err, data) {
  if (err) {
    console.log(err);
  } else {
    console.log(data.toString());
  }
})
//  写文件
fs.writeFile('./20180926 demo/b.text', 'this is node.js', function (err) {
  if (err) {
    console.log(err);
  } else {
    console.log('文件写入成功');
  }
})
View Code

 2.最简 http

let http = require('http')
let server = http.createServer()
server.on('request', function (req, res) {
  console.log('请求路径', req.url);
  // res.write('123');   // write 发送数据  以 end 结尾
  // res.end('455');   //  直接 end 就可以了
  if (req.url === '/') {    // 原生 http 只能这样判断不同的请求
    res.end('index')
    // res.end(333)   // end值 必须是二进制或者字符串
  } else {
    res.end('404 no found')
  }
})
server.listen('3333', function () {
  console.log('服务器创建成功,可通过http://localhost:3333来访问');
})
View Code

 3. 核心模块  如 os 操作系统模块 不常用 

let os = require('os') // 操作系统模块  不常用
console.log(os.cpus());
console.log(os.totalmem());
View Code

 4. exports  require 简单应用

a.js

let foo = 'abcdefg'
console.log('aaaa');
exports.foo2 = 'hello'  // 导出给其他文件用,默认是一个空对象
exports.add = function (x, y) {
  return x + y
}

test.js

console.log('引入a文件');
// require('./a.js')
let res = require('./a') // 可以省略后缀名   ./ 不可省略
// 引进来是一个对象
console.log(res.foo2);
console.log(res.add(10, 20));
//  require('path')  ./省略会识别为 核心模块,如path
/*
* node 没有全局作用域,只有模块作用域,即 当前文件test.js无法访问其他文件a.js的变量数据
*
* */

 5.content-type  http读html 图片

// nodejs.org
/*
* ip 地址用来定位计算机
* 端口号用来定位具体的应用程序(所有需要联网的都需要端口号)
* 所有联网的应用程序都会占用一个端口号
* 端口号范围 0 ~ 65536
*
* */
let http= require('http')
let fs= require('fs')
let server = http.createServer()
/*
* 服务器默认发送 utf8编码
* 浏览器默认根据中文操作系统来识别 ,默认为 gbk
*
* Content-type: text/plains 普通文本
*               text/html  html
*               image/jpeg  图片
*  tool.oschina.net  查所有的 content-type
* */
server.on('request',function (req, res) {
  console.log('请求我的客户端的地址是:', req.socket.remoteAddress, req.socket.remotePort)
  // res.setHeader('Content-Type','text/html;charset=utf-8')
  // res.end('<a href="">中国</a>')

  // 读html的内容
  fs.readFile('./index.html', function (err, data) {
    //  读图片
    // fs.readFile('./resource/ab2.jpg', function (err, data) {
    if (err) {
      res.setHeader('Content-Type', 'text/plain; charset=utf-8')
      res.end('文件读取失败,请稍后重试!')
    } else {
      res.setHeader('Content-Type', 'text/html; charset=utf-8')
      // res.setHeader('Content-Type', 'image/jpeg')
      res.end(data)
    }
  })
  //
})
server.listen(3333,function () {
  console.log('server is running');
})

 6.使用 readFile() 实现 类似apache的www目录访问

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

var server = http.createServer()

var wwwDir = 'D:/Movie/www'

server.on('request', function (req, res) {
  var url = req.url
  // 访问路径              访问的资源 
  // /                     index.html
  // /a.txt                wwwDir + /a.txt
  // /apple/login.html     wwwDir + /apple/login.html
  // /img/ab1.jpg          wwwDir + /img/ab1.jpg     
  

  var filePath = '/index.html'
  if (url !== '/') {
    filePath = url
  }

  fs.readFile(wwwDir + filePath, function (err, data) {  
    // 通过读文件 readFile 渲染对应资源
    if (err) {
      return res.end('404 Not Found.')
    }
    res.end(data)
  })
})

// 3. 绑定端口号,启动服务
server.listen(3000, function () {
  console.log('running...')
})
View Code

 7.js代码风格   webstorm已支持 javascript standard style    分号问题,   ( [ `   以这三个开头的代码前面加 ; 其他代码不用加分号

;(function(){...})()

/*
*   js 代码风格
*   https://standardjs.com/readme-zhcn.html
*   webstorm 2017版支持 javascript standard style
*   设置  Editor | Code style | JavaScript and click Set from Predefined Style – Standard and the style will replace your current scheme.
*   按格式化 ctrl+alt+l 会自动删除分号,把"" 换为 ''
*   当代码以 ( [ ` 开头时,要在前面加;号
* */
//  ( 开头
;(function () {
  console.log('444')
})()
// [ 开头
;['a','b'].forEach((val)=>{
  console.log(val)
})
// ` 开头
;`abc`.toString()       //   `` 这里类似 <pre></pre>
let foo = `
12345      床前明月光   
456 
`
console.log(foo)
View Code

 8.

/*
* 客户端渲染不利于 seo
* 服务端渲染可以被爬虫抓取到,
* 京东商品列表是服务端渲染,seo优化,产品才能被搜到,
*     商品评论列表是客户端渲染,不刷新,体验好
*
* */

 9.代码风格

代码块适当加空行,容易阅读
常量  MAX_MONEY = 10
var  person = null;  定义变量为null 

for(xxx){
    if(y===2){
        continue;   
    }
    process(y)
}    

//  continue 可换成if判断

for(xxx){
    if(y!==2){
      process(y)
    }
}

【所有的var语句都提前到包含这段逻辑的函数的顶部执行】
function doSomething() {
     var result = 10 + value;
     var value = 10;
     return result;
}

真正的执行顺序:
function doSomething() {
     var result;
     var value;     //  var 先执行
     result = 10 + value;
     value = 10;
     return result;
}

 //  2   
function doSomethingWithItems(items) {
     for (var i=0, len=items.length; i < len; i++) {
         doSomething(items[i]);
    }
}
真正的执行顺序:
function doSomethingWithItems(items) {
     var i, len;   // var 先执行
     for (i=0, len=items.length; i < len; i++) {
         doSomething(items[i]);
     }
}
建议总是将局部变量的定义作为函数内第一条语句。


使用 instanceof
// 检测日期
if (value instanceof Date) {
     console.log(value.getFullYear());
}

// 检测正则表达式
if (value instanceof RegExp) {
     if (value.test(anotherValue)) {
         console.log("Matches");
    }
}

 10 module.exports 和 exports    

exports = module.exports
// 最终使用
// 导出多个成员 exports.xxx = xxx exports.yyy = yyy
// 导出多个成员也可以 module.exports = {}
// 导出单个成员 module.exports= xxx
// 也可以不管 exports
/*
* 在 Node 中,每个模块内部都有一个自己的 module 对象
* 该 module 对象中,有一个成员叫:exports 也是一个对象
*
*   var module = {
*     exports:{
*       ...
*     }
*   }
*
*  return module.exports
*
*
* 默认在代码的最后有一句: return module.exports
* 所以,直接给 module.exports对象赋值后,require引起来可得到该数据
*   module.exports.test='123'
*   node 模块中,有如下定义
*  var exports = module.exports
*  两者相等  exports 是 module.exports的一个引用
*    exports.foo='bar'
*    等价于
*    module.exports.foo='bar'
*
* */



// 导出多个(必须在对象中)
/*exports.foo2 = 'hello'  // 导出给其他文件用,默认是一个空对象
exports.add = function (x, y) {
  return x + y
}*/
/*
*   let obj = require('xx.js')
*   obj.foo2
*   obj.add(3,4)
*
*
* */

//  方式 二
module.exports = {
  add: function (x, y) {
    return x + 2*y
  },
  str: 'abc'
}

/*
* let obj = require('xx.js')
*   obj.add(3,4)
*   obj.str
*
* */

// 方式 三   // 只导出一个
/*
*  如果 exports=function(x,y){return x+3*y}  则导出失败
*  已经把 exports重新赋值了,exports不等于 module.exports了
* */
module.exports=function(x,y){
  return x+3*y
}

/*
* let add = require('xx.js')
*   add(3,4)
*
* */

var obj = {}
var obj1 = obj;
obj1.foo='123'
console.log(obj.foo) //   123
obj1={}           //  重新赋值了,跟 obj 没关系 了
obj1.foo='test'
console.log(obj.foo)  //  123


// 最终使用
// 导出多个成员  exports.xxx = xxx  exports.yyy = yyy
// 导出多个成员也可以  module.exports = {}
// 导出单个成员   module.exports= xxx
// 也可以不管 exports
View Code

 11 require()  npm 细节 

/*
* main.js
* require('./a')
* require('./b')    //  优先从缓存中加载 代码只执行一次,但module.exports 会多次调用
*
*
*  a.js
*  console.log('a')
*  require('./b')
*
*
*  b.js
*  console.log('b')
*  module.exports.test='abc'
*
* node main.js   b.js 只加载一次,只输出一次console.log('b') 但b.js 中的 test会执行两次
* */

/*
*  npm i art-template
*  require('art-template')  // 直接require 安装的包名
*  实际加载的是  node_modules/art-template/package.json 里面的 main 属性
*  如果没有 package.json 或者 main属性,则默认加载 index.js
*  如果以上都没有,则会往上一级目录查找
*  node_modules 一般放在项目根目录,供所有子目录文件加载使用
* */

// npm i -S 包名
// npm un -S 包名  删除
// npm i --global cnpm   安装淘宝的 cnpm  以后用 cnpm 代替 npm   方法一
// npm config set registry https://registry.npm.taobao.org     方法二
// npm config list // 查看淘宝镜像配置信息
View Code

 12  express 静态资源拖管  app.use('/public', express.static('public'))

// 公开访问public 目录  1
app.use('/public', express.static('public'))
// app.use('/a',express.static('public'))  // 可以搞个别名a指向public   /a/logo.png
// http://localhost:3333/public/logo.png  地址栏可访问public 目录下的所有数据

// 公开访问public 目录  2   // 不常用
// app.use(express.static('public'))
// http://localhost:3333/logo.png  地址栏可访问public 目录下的所有数据
View Code

 13. mongodb 基础

mongodb.com 下载数据库v3.6.7,安装 

custom-> 安装在d 盘,取消勾选左侧的Install MongoDB Copmpass”选项,其他默认

可视化工具 robo 3T 
 
文档 https://mongoosejs.com/  

mongoose是mongoDB的一个对象模型工具,封装了mongoDB对文档的一些增删改查等常用方法,让nodejs操作mongoDB数据库变得更加容易。

关系型数据库 mySQL
非关系型数据库 MongoDB 不需要设计表结构
数据表-   集合(数组)
表记录-   文档对象
View Code

14. mongodb 纯数据库操作

环境变量 path:  D:\MongoDB\bin;  mongod --version    
mongod 数据默认存储目录 当前根目录/data/db    【需要手动创建文件夹,在c盘/d盘执行就是   c:/data /db  d:/data/db】
启动数据库  mongod        省略环境变量的配置则要进入到对应目录再执行 mongod
连接数据库  mongo   退出 exit
查看数据库 show dbs
切换  use 
查看  db 

集合 show collections (对应mysql中的表)

插入 db.students.insertOne({"name":"Jack"})
查找 db.students.find()
View Code

15.mongodb 基本概念

基本概念
mongodb数据库, qq集合(数据表),baidu集合(数据表),一个集合有多个文档(表记录) users文档,products文档
{
    qq:{
        users:[{},{}],
        products:[{}]
    },
    baidu:{
    
    }
}
View Code

16.mongodb 增删查改  有很多个函数可以用   save()    deleteOne()    find()     updateOne

/*
* 文档  https://mongoosejs.com/
*
*
* */

const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/test', {
  useNewUrlParser: true
})

// 文档结构(表结构)
let userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true
  },
  email: {
    type: String,
  },
  gender:{
    type:Number,
    enum:[0,1],  // 枚举
    default:0
  }
})
//  模型    最终集合名称为  users
const User = mongoose.model('User', userSchema)

//
/*let user = new User({
  username:'jia',
  email:'jia@qq.com'
})
user.save(function (err,res) {
  if(err){
    console.log(err)
  }
  console.log(res)
})*/
//
User.find(function (err, res) {
  if (err) {
    console.log(err + '11')
  }
  console.log(res)
})
// 查条件
/*User.findOne({username:'kang'}, function (err, res) {
  if (err) {
    console.log(err)
  }
  console.log(res)
})*/
// findOne 返回对象  find 返回数组对象

// 删除 remove 改成 deleteOne deleteMany
/*User.deleteMany({_id:'5bbeab08393ed015589a044a'},function (err, res) {
  if(err){
    console.log(err)
  }
  console.log('删除成功')
  console.log(res)
})*/
// 有好多种删除
/*User.findByIdAndRemove('5bbdb56c29c8f01684091b28',function (err) {
  if(err){
    console.log(err)
  }
  console.log('删除成功')
})*/

// 更新
/*User.updateOne({username:'kang'},{email:'什么都可以@ee.com'},function (err, res) {
  if(err){
    console.log(err)
  }
  console.log('更新成功')
})*/

 17. path.join 的使用

let path = require('path')
console.log(path.join('c:a/b/', '/c'))  // path.join  路径拼接,防出错
console.log(path.join('c:a/b/', 'c'))  // 两者一致
console.log(__filename)  // 文件路径   e:/node0823/test.js
console.log(__dirname)  //  目录      e:/node0823
/*
* D:\businessCenter   windows 目录是反斜杠 \   mac 是 斜杠 /
* */

/*
*  涉及到文件操作的,path.join(__dirname,'xx') 防路径出错
* */
let fs = require('fs')
// let path2='./a.txt';  // 相对于执行node命令所处的终端路径 会出错,使用
let path2 = path.join(__dirname,'a.txt')
fs.readFile(path2,'utf8',function (err, res) {
  if(err){
    console.log(err)
  }
  console.log(res)
})

18. express-session

/*
* express-session
* npm i express-session
* 该插件会为 req 请求对象 添加一个成员: req.session 默认是个对象
* 默认session 数据 是内存存储的,服务器一旦重启就会丢失,生产环境会把 sessioin持久化存储
* 生产环境时,使用插件把 session保存到数据库中,
*
* */

var session = require('express-session')
app.use(session({
  secret: 'kang',   // 配置加密字符串,它会在原有加密基础之上和这个字符串拼起来去加密,增加安全性
  resave: false,
  saveUninitialized: false // 无论你是否使用 Session ,我都默认直接给你分配一把钥匙
}))

// 添加 session 数据
// req.session.user=user  // 保存用户数据到 session


// 获取 session 数据
// req.session.user
// session 在后端直接渲染页面时,用得到,前后端分离可能用不到它
 

 19  express  app.use() 中间件  错误统一处理

let express = require('express')
let app = express()
let fs = require('fs')
/*
*  没路径的中间件会执行 要 next() 执行下一个中间件
* */
/*app.use(function (req, res, next) {
  res.send('中国人')
  console.log(1)
  next()
})

app.use(function (req, res, next) {
  console.log(2)
})*/

/*
* 以路径 /x 开头的  要 next() 执行下一个中间件
*
* */
app.use('/ad',function (req, res, next) {
  console.log(req.url)
  res.send('end')
  // res.render('404.html') // 渲染404错误页面
})

app.get('/',function (req, res, next) {
  fs.readFile('dfdfdf',function (err, res) {
    if(err) {
      return next(err)  // 传递错误
    }
  })
})
app.get('/login',function (req, res, next) {
  // ...
  user.findOne({username:'xx'},function (err, res) {
    if(err){
      return next(err)  // 返回 next(err)
    }
  })
})

/*
*  错误统一处理,
* */
app.use(function (err, req, res, next) {
  res.status(500).send(err.message)
})

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

 commander 命令行参数

var program = require('commander');  // 获取命令行参数
var colors=require('colors')

program
  .version('0.1.0')
  .option('-f, --folder <string>', 'add folder')
  .parse(process.argv);  // 原生获取命令行参数 process.argv

// node xx.js -f guild
console.log('folder',program.folder);  // guild
console.log('abc'.red);  // 红色字体

 

posted @ 2018-09-27 09:36  gyz418  阅读(224)  评论(9编辑  收藏  举报