Node.js基础入门(二)


模块/包 与 CommonJS

1、模块/包分类

Node.js 有三类模块,即内置的核心模块、第三方的模块、自定义的模块。

1.1 内置的模块

Node.js 内置模块又叫核心模块,Node.js安装完成可直接使用。如:

const path = require('path');
console.log(path.extname('index.html'));

1.2 第三方的Node.js模块

第三方的Node.js模块指的是为了实现某些功能,发布的npmjs.org上的模块,按照一定的开源协议供社群使用。如:

npm install chalk
const chalk = require('chalk')
console.log(chalk.blue('Hello world!'))

1.3 自定义的Node.js模块

自定义的Node.js模块,也叫文件模块,是我们自己写的供自己使用的模块。同时,这类模块发布到npmjs.org上就成了开源的第三方模块。

自定义模块是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程、速度相比核心模块稍微慢一些,但是用的非常多。

2、CommonJS

CommonJs 是一种 JavaScript 语言的模块化规范,它通常会在服务端的 Nodejs上使用。项目是由多个模块组成的,模块和模块之间的调用,需要各个模块有相同规范的 API,这样一来在使用的过程中不会有那么多的学习成本,并且对于单个模块来说是类聚的。

2.1 模块定义、接口暴露和引用接口

在 CommonJs的模块化规范中,每一个文件就是一个模块,拥有自己独立的作用域、变量、以及方法等,对其他的模块都不可见。CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的 exports 属性(module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。require方法用于加载模块。

创建m1.js文件,添加内容,定义模块m1

const name = '19'
const sayName = () => {
  console.log(name)
}

console.log('module 1')

// 接口暴露方法一:
module.exports = {
  say: sayName
}

// 接口暴露方法二:
exports.say = sayName

// 错误!
exports = {
  say: sayName
}

在main.js中引用模块m1

const m1 = require('./m1')
m1.say()

常用内置模块

1. url

1.1 parse

url.parse(urlString[, parseQueryString[, slashesDenoteHost]]);将url解析为一个对象

const url = require('url');
const urlStr = 'http://www.baidu.com:443/path/index.html?id=2#tag=3';
console.log(url.parse(urlStr));

运行结果
在这里插入图片描述

1.2 format

url.format(urlObject);将一个url对象解析成一个字符串。

const url = require('url')
const urlObj {
  protocol: 'http:',
  slashes: true,
  auth: null,
  host: 'www.baidu.com:443',
  port: '443',
  hostname: 'www.baidu.com',
  hash: '#tag=3',
  search: '?id=2',
  query: 'id=2',
  pathname: '/path/index.html',
  path: '/path/index.html?id=2',
  href: 'http://www.baidu.com:443/path/index.html?id=2#tag=3'
};
const urlTest = url.format(urlObject)
console.log(urlTest )

运行结果
在这里插入图片描述

1.3 resolve

url.resolve(from, to) 按规则解析url

const url = require('url');
console.log(url.resolve('https://www.baidu.com/a', '../'));
console.log(url.resolve('https://www.baidu.com/a', '/b'));

运行结果
在这里插入图片描述

1.4 URLSearchParams

解析url中后边的内容

const url = require('url');
const urlStr = 'http://www.baidu.com:443/path/index.html?id=2#tag=3';
const urlParams = new URLSearchParams(url.parse(urlStr).search);
console.log(urlParams.get('id'));//获取id

运行结果
在这里插入图片描述

2、querystring

2.1 parse

querystring.parse(str[, sep[, eq[, options]]]);将字符串解析为对象

const querystring = require('querystring')
var s = 'x=3/&y=4'
//参数一:每组key,value之间的分隔符,参数二:key,value之间的分隔符
var parsed = querystring.parse(s, '&', '=')

var parsed = querystring.parse(s)
console.log(parsed)

运行结果

带参数
在这里插入图片描述
不带参数
在这里插入图片描述

2.2 stringify

querystring.stringify(obj[, sep[, eq[, options]]])

const querystring = require('querystring')
var o = {
  x: 3,
  y: '位'
}
//带参数,参数一:每组key,value之间的分隔符,参数二:key,value之间的分隔符
var parsed1 = querystring.stringify(o, ':', '/')
//不带参数
var parsed2 = querystring.stringify(o)
//不将中文编码
var parsed3 = querystring.stringify(o, null, null, {
    encodeURIComponent(string) {
        return querystring.unescape(string);
    }
})
console.log(parsed3)

带参数运行结果(会默认将中文编码)
在这里插入图片描述
不带参数运行结果在这里插入图片描述
不将中文编码
在这里插入图片描述

2.3 escape/unescape

querystring.escape(str)将字符串编码

const querystring = require('querystring')
var str = 'id=3&city=北京&url=https://www.baidu.com'
var escaped = querystring.escape(str)
console.log(escaped)
querystring.unescape(str)

在这里插入图片描述

const querystring = require('querystring')
var str = 'id%3D3%26city%3D%E5%8C%97%E4%BA%AC%26url%3Dhttps%3A%2F%2Fwww.baidu.com'
var unescaped = querystring.unescape(str)
console.log(unescaped)

在这里插入图片描述

3、http/https

3.1 get

var http = require('http')
var https = require('https')

// 1、接口 2、跨域
const server = http.createServer((request, response) => {
  var url = request.url.substr(1)

  var data = ''

  response.writeHeader(200, {
  	//默认,会自动解析html代码
  	'content-type': 'text/html',
  	
  	//不会自动解析html代码
  	//'content-type': 'text/plain',
  	
	//返回json字符串
    //'content-type': 'application/json;charset=utf-8',
    
    //'Access-Control-Allow-Origin': '*'
  })
  //会在前端页面显示 hello,并且需要在后边加上end停止
  //response.write('hello')
  //response.end();
  
  https.get(`https://m.lagou.com/listmore.json${url}`, (res) => {

    res.on('data', (chunk) => {
      data += chunk
    })

    res.on('end', () => {
      response.end(JSON.stringify({
        ret: true,
        data
      }))
    })
  })

})

server.listen(8080, () => {
  console.log('localhost:8080')
})

3.2 post:服务器提交

const https = require('https')
const querystring = require('querystring')

const postData = querystring.stringify({
  province: '上海',
  city: '上海',
  district: '宝山区',
  address: '同济支路199号智慧七立方3号楼2-4层',
  latitude: 43.0,
  longitude: 160.0,
  message: '求购一条小鱼',
  contact: '13666666',
  type: 'sell',
  time: 1571217561
})

const options = {
  protocol: 'https:',
  hostname: 'ik9hkddr.qcloud.la',
  method: 'POST',
  port: 443,
  path: '/index.php/trade/add_item',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': Buffer.byteLength(postData)
  }
}

function doPost() {
  let data

  let req = https.request(options, (res) => {
    res.on('data', chunk => data += chunk)
    res.on('end', () => {
      console.log(data)
    })
  })

  req.write(postData)
  req.end()
}

// setInterval(() => {
//   doPost()
// }, 1000)

3.3 跨域:jsonp

利用的是在浏览器端请求一个js不跨域的特性

const http = require('http')
const url = require('url')

const app = http.createServer((req, res) => {
  let urlObj = url.parse(req.url, true)

  switch (urlObj.pathname) {
    case '/api/user':
      res.end(`${urlObj.query.cb}({"name": "gp145"})`)
      break
    default:
      res.end('404.')
      break
  }
})

app.listen(8080, () => {
  console.log('localhost:8080')
})

3.4 跨域:CORS

跨源资源共享


const http = require('http')
const url = require('url')
const querystring = require('querystring')

const app = http.createServer((req, res) => {
  let data = ''
  let urlObj = url.parse(req.url, true)

  res.writeHead(200, {
    'content-type': 'application/json;charset=utf-8',
    //跨域
    'Access-Control-Allow-Origin': '*'
  })

  req.on('data', (chunk) => {
    data += chunk
  })

  req.on('end', () => {
    responseResult(querystring.parse(data))
  })

  function responseResult(data) {
    switch (urlObj.pathname) {
      case '/api/login':
        res.end(JSON.stringify({
          message: data
        }))
        break
      default:
        res.end('404.')
        break
    }
  }
})

app.listen(8080, () => {
  console.log('localhost:8080')
})

3.5 跨域:middleware(http-proxy-middware)

const http = require('http')
const proxy = require('http-proxy-middleware')

http.createServer((req, res) => {
  let url = req.url

  res.writeHead(200, {
    'Access-Control-Allow-Origin': '*'
  })

  if (/^\/api/.test(url)) {
    let apiProxy = proxy('/api', { 
      target: 'https://m.lagou.com',
      changeOrigin: true,
      pathRewrite: {
        '^/api': ''
      }
    })

    // http-proy-middleware 在Node.js中使用的方法
    apiProxy(req, res)
  } else {
    switch (url) {
      case '/index.html':
        res.end('index.html')
        break
      case '/search.html':
        res.end('search.html')
        break
      default:
        res.end('[404]page not found.')
    }
  }
}).listen(8080)

4、Events

const EventEmitter = require('events')
//继承
class MyEventEmitter extends EventEmitter {}
//实例
const event = new MyEventEmitter()
//定义play事件
event.on('play', (movie) => {
  console.log(movie)
})
//该事件只能触发一次
event.once('play1', (movie) => {
  console.log(movie)
})
//触发play事件
event.emit('play', '我')
event.emit('play', '中国')

5、File System

const fs = require('fs')
const fsP = require('fs').promises

// 创建文件夹 
//参数一:文件名
//参数二:错误优先的回调函数
fs.mkdir('./logs', (err) => {
  console.log('done.')
})

// 文件夹改名
fs.rename('./logs', './log', () => {
  console.log('done')
})

// 读取文件夹
fs.readdir('./logs', (err, result) => {
	//返回文件夹下的文件名数组
  console.log(result)
})

// 删除文件夹
fs.rmdir('./log', () => {
  console.log('done.')
})

// 写内容到文件里
fs.writeFile(
	//要写入的文件
  './logs/log1.txt',
  //要写入的内容
  'hello',
  // 错误优先的回调函数
  (err) => {
    if (err) {
      console.log(err.message)
    } else {
      console.log('文件创建成功')
    }
  }
)

// 给文件追加内容
fs.appendFile('./logs/log1.txt', '\nworld', () => {
  console.log('done.')
})

// 读取文件内容
//参数二:读出结果采用utf-8编码
fs.readFile('./logs/log1.txt', 'utf-8', (err, data) => {
  console.log(data)
})

// 删除文件
fs.unlink('./logs/log1.txt', (err) => {
  console.log('done.')
})

// 批量写文件
for (var i = 0; i < 10; i++) {
  fs.writeFile(`./logs/log-${i}.txt`, `log-${i}`, (err) => {
    console.log('done.')
  })
}

// 读取文件/目录信息
fs.readdir('./', (err, data) => {
  data.forEach((value, index) => {
    fs.stat(`./${value}`, (err, stats) => {
      // console.log(value + ':' + stats.size)
      console.log(value + ' is ' + (stats.isDirectory() ? 'directory' : 'file'))
    })
  })
})

// 同步读取文件
try {
  const content = fs.readFileSync('./logs/log-1.txt', 'utf-8')
  console.log(content)
  console.log(0)
} catch (e) {
  console.log(e.message)
}

console.log(1)

// 异步读取文件:方法一
fs.readFile('./logs/log-0.txt', 'utf-8', (err, content) => {
  console.log(content)
  console.log(0)
})
console.log(1)

// 异步读取文件:方法二
fs.readFile('./logs/log-0.txt', 'utf-8').then(result => {
  console.log(result)
})

// 异步读取文件:方法三
function getFile() {
  return new Promise((resolve) => {
    fs.readFile('./logs/log-0.txt', 'utf-8', (err, data) => {
      resolve(data)
    })
  })
}

;(async () => {
  console.log(await getFile())
})()

// 异步读取文件:方法四
const fsp = fsP.readFile('./logs/log-1.txt', 'utf-8').then((result) => {
  console.log(result)
})

console.log(fsP)

// watch 监测文件变化
fs.watch('./logs/log-0.txt', () => {
  console.log(0)
})
fs.watchFile('./logs/log-0.txt', () => {
  console.log(1)
})

6、Stream

const fs = require('fs')
//读流
const readstream = fs.createReadStream('./note.txt')
//写流
const writestream = fs.createWriteStream('./note2.txt')

writestream.write(readstream)

7、Zlib

const fs = require('fs')
//压缩
const zlib = require('zlib')

const gzip = zlib.createGzip()

const readstream = fs.createReadStream('./note.txt')
const writestream = fs.createWriteStream('./note2.gzip')

readstream
	//压缩
  .pipe(gzip)
  .pipe(writestream)

//writestream.write(readstream)

8、ReadLine

//一行一行的读
const readline = require('readline')

const rl = readline.createInterface({
	//标准输入
  input: process.stdin,
  //标准输出
  output: process.stdout
})
//会停下来等你输入,输入完成后再继续往下走
rl.question('What do you think of Node.js? ', (answer) => {
  // 输入的答案保存在answer中
  console.log(`Thank you for your valuable feedback: ${answer}`)

  rl.close()
})

9、Crypto

加密:既可作对称加密,也可做非对称加密,还可以做MD5加密、sha加密

const crypto = require('crypto')

const secret = 'abcdefg'
//参数一:加密算法
//参数二:加密对象
const hash = crypto.createHmac('sha256', secret)
					//若有中文,要加编码方式
                   .update('I love you', /*'utf-8'*/)
                   //以16进制去加密
                   .digest('hex')
console.log(hash)

路由

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

http.createServer( function ( req, res ) {

  switch ( req.url ) {
    case '/home':
      res.write('home')
      res.end()
      break
    case '/mine':
      res.write('mine')
      res.end()
      break
    case '/login': 
      fs.readFile( './static/login.html',function ( error , data ) {
        if ( error ) throw error  
        res.write( data )
        res.end()
      })
      break
    case '/fulian.jpg':
      fs.readFile( './static/fulian.jpg', 'binary', function( error , data ) {
        if( error ) throw error 
        res.write( data, 'binary' )
        res.end()
      })
      break
    default: 
      break
   }

 }).listen( 8000, 'localhost', function () {
   console.log( '服务器运行在: http://localhost:8000' )
 })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值