1、什么是Node
-
Node.js 是一个基于Chrome V8 引擎的JavaScript运行环境
-
Node.js使用了一个事件驱动、非阻塞式I/O的模型,使其轻量又高效
事件驱动: 任务执行,发布者,订阅者,事件驱动 ( on emit )
非阻塞: 执行某一个任务的同时也可以执行其他任务(异步)
阻塞: 执行某一个任务,这个任务如果没有执行完成,其他任务必须等待(同步)
I/O: 输入/输出( 数据库操作,文件系统操作等 )
非阻塞I/O模型: 当我们使用Node.js来实现数据库操作、文件系统等操作时,要进行的异步操作,异步操作的核心传统实现方式就是回调函数。
两大类异步:回调函数和事件
-
Node.js的包管理工具npm,是全球最大的开源库生态系统。
第三方: 国外的
建议: 切换国内的, 淘宝国内镜像源
1.nrm安装
2.cnpm:
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
查看是否cnpm安装成功
cnpm -v
2、Node.js实时监听(自动刷新)
- nodemon:
- cnpm i nodemon -g
- nodemon 文件名称
- supervisor
- cnpm i supervisor -g
- supervisor 文件名称
3、前端模块化(commonjs规范)
前言:前端的模块化(AMD CMD commonjs)
AMD:require.js
CMD:sea.js
commonjs:node.js(Node 应用由模块组成,采用 CommonJS 模块规范。)
模块的分类:
-
内置模块
-
const/var/let 变量名 = require( 模块名 )
-
使用API(说明文档)
总结:内置模块直接引用,引入后使用它的API。
const qs = require('querystring') var str = 'http://www.baidu.com/home?a=1&b=2#c=3' // parse console.log(qs.parse(str)) // { 'http://www.baidu.com/home?a': '1', b: '2#c=3' }
-
-
自定义模块
- 创建模块(对象,数组,字符串,函数)
const people = { card: 1003, name: '张三', sex: 'man', age: 20 }
- 导出模块(为了安全一般包装一下再导出)
module.exports = {people}
- 引入模块并使用(在不同的文件中)
const { people } = require('./02-my-self');//切记这里是相对路径 // 直接使用 console.log(people.name)
-
第三方模块
//首先安装插件npm install 插件名 -S/-D const request=require("request");//引用插件 request.get('http://api.douban.com/v2/movie/in_theaters', (err, response, body) => { if (!err) { // console.log(body); console.log(JSON.parse(body)) } else { console.log(err); } })
4、常用的内置模块
-
URL 网址解析(模块用于处理与解析 URL)
const url = require('url');
-
解析 URL 字符串并返回 URL 对象。url.parse()
url.parse(urlString[,parseQueryString[,slashesDenoteHost]])
-
返回一个WHATWG URL对象的可自定义序列化的URL字符串表达。url.format(URL[, options])
// 虽然URL对象的toString()方法和href属性都可以返回URL的序列化的字符串。然而,两者都不可以被自定义。而url.format(URL[, options])方法允许输出的基本自定义。 const { URL } = require('url'); const myURL = new URL('https://a:b@你好你好?abc#foo'); console.log(myURL.href); // 输出 https://a:b@xn--6qqa088eba/?abc#foo console.log(myURL.toString()); // 输出 https://a:b@xn--6qqa088eba/?abc#foo console.log(url.format(myURL, { fragment: false, unicode: true, auth: false })); // 输出 'https://你好你好/?abc'
-
url.resolve(from, to)方法会以一种 Web 浏览器解析超链接的方式把一个目标 URL 解析成相对于一个基础 URL。
const url = require('url'); url.resolve('/one/two/three', 'four'); // '/one/two/four' url.resolve('http://example.com/', '/one'); // 'http://example.com/one' url.resolve('http://example.com/one', '/two'); // 'http://example.com/two'
-
-
QueryString 参数处理。
querystring
模块提供用于解析和格式化 URL 查询字符串的实用工具。- querystring.escape(str)
- querystring.unescape(str)
- querystring.parse(str[, sep[, eq[, options]]])
- querystring.stringify(obj[, sep[, eq[, options]]])
-
HTTP 模块概要
-
http.get(options[, callback])/http.get(url[,options][,callback])
http.get('http://nodejs.cn/index.json', (res) => { const { statusCode } = res;//获取请求的状态码 const contentType = res.headers['content-type'];// 获取请求类型,数据类型 let error; if (statusCode !== 200) {//如果状态码不是200的话输出报错信息 error = new Error('请求失败\n' + `状态码: ${statusCode}`); } else if (!/^application\/json/.test(contentType)) { error = new Error('无效的 content-type.\n' + `期望的是 application/json 但接收到的是 ${contentType}`); } if (error) {//如果报错了,将报错信息存入日志。 console.error(error.message); // 消费响应数据来释放内存。 res.resume(); return; } res.setEncoding('utf8');//字符编码 let rawData = ''; res.on('data', (chunk) => { rawData += chunk; });//通过data事件拼接数据流 res.on('end', () => {//获取数据结束了 try { const parsedData = JSON.parse(rawData); console.log(parsedData); } catch (e) { console.error(e.message); } }); }).on('error', (e) => { console.error(`出现错误: ${e.message}`); });
-
http.request(options[, callback])/http.request(url[,options][,callback])
const postData = querystring.stringify({ 'msg': '你好世界' }); const options = { hostname: 'nodejs.cn', port: 80, path: '/upload', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; const req = http.request(options, (res) => { console.log(`状态码: ${res.statusCode}`); console.log(`响应头: ${JSON.stringify(res.headers)}`); res.setEncoding('utf8'); res.on('data', (chunk) => { console.log(`响应主体: ${chunk}`); }); res.on('end', () => { console.log('响应中已无数据'); }); }); req.on('error', (e) => { console.error(`请求遇到问题: ${e.message}`); }); // 将数据写入请求主体。 req.write(postData); req.end();
-
http实现简单的爬虫
-
思路:去网站爬取一段数据(应用于后端渲染出来的网站)->数据清洗->后端服务器->发送前端->渲染数据
前端渲染和后端渲染的区别?
后端渲染(SSR、服务端渲染)
后端渲染HTML的情况下,浏览器会直接接收到经过服务器计算之后的呈现给用户的最终的HTML字符串,这里的计算就是服务器经过解析存放在服务器端的模板文件来完成的,在这种情况下,浏览器只进行了HTML的解析,以及通过操作系统提供的操纵显示器显示内容的系统调用在显示器上把HTML所代表的图像显示给用户。 前端渲染(SPA、单页面应用)
前端渲染就是指浏览器会从后端得到一些信息,这些信息或许是适用于题主所说的angularjs的模板文件,亦或是JSON等各种数据交换格式所包装的数据,甚至是直接的合法的HTML字符串。这些形式都不重要,重要的是,将这些信息组织排列形成最终可读的HTML字符串是由浏览器来完成的,在形成了HTML字符串之后,再进行显示。const http = require('http') // 引入第三方类库cheerio //Cheerio实现了核心jQuery的一个子集。Cheerio从jQuery库中删除了所有DOM不一致和浏览器残骸,揭示了它真正华丽的API。 const cheerio = require('cheerio') const options = { hostname: 'nodejs.cn', port: 80, path: '/upload', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; http.get(options, (res) => { const { statusCode } = res; const contentType = res.headers['content-type']; res.setEncoding('utf8'); let rawData = ''; res.on('data', (chunk) => { rawData += chunk; }); res.on('end', () => { try { //!!!cheerio的应用 const $ = cheerio.load(rawData) $('.student a').each(function (index, item) { console.log($(this).text() + '---' + index) }) } catch (e) { console.error(e.message); } }); }).on('error', (e) => { console.error(`Got error: ${e.message}`); });
-
-
http.createServer([options][, requestListener])
-
如何使用Node创建一个静态的服务器
const http = require('http') const host = 'localhost' const port = 8000 http.createServer((request, response) => { // response.writeHead( 状态码,请求头 ) response.writeHead(200, { 'Content-type': 'text/html;charset=utf8' }) response.write('<h3> 这里使用Node创建的一个静态服务器 </h3>') // 往前端发送信息 response.end() // 告诉前端信息已经结束了 }).listen(port, host, () => { console.log(`The server is running at: http://${host}:${port}`) })
-
-
-
事件 events 模块
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', () => { console.log('触发事件'); }); myEmitter.emit('event');
-
文件fs模块(Node.js读取文件都是二进制流。buffer 、binary)
const fs = require('fs');
fs.readFile(path[, options], callback)
fs.readFile('/etc/passwd', (err, data) => { if (err) throw err; console.log(data); });
//如果 options 是字符串,则它指定字符编码 fs.readFile('/etc/passwd', 'utf8', callback);
-
Stream 流模块
- 什么是流?Node中为什么要有流这个概念?使用场景?
答:流指的是数据流,指的是数据的分片传输。有了流可以实现非阻塞。gulp就是流式操作。
案例:打包压缩包
/*思路: 1、读取文件 2、创建压缩包 3、将读取的数据流写入压缩包 4、输出压缩包 */ const fs = require('fs') // 读取所要压缩的文件 const zlib = require('zlib') // 创建压缩包 const inp = fs.createReadStream( 相对路径 )//读出数据 const gzip = zlib.createGzip() // 创建压缩包 const outp = fs.createWriteStream(相对路径)//输出压缩包 inp .pipe( gzip ) .pipe( outp )