700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 唤醒手腕 - 前端服务器端开发 Node.Js 学习笔记(学习中 更新中)

唤醒手腕 - 前端服务器端开发 Node.Js 学习笔记(学习中 更新中)

时间:2023-02-15 15:59:01

相关推荐

唤醒手腕 - 前端服务器端开发 Node.Js 学习笔记(学习中 更新中)

唤醒手腕 - Node.Js 学习笔记

唤醒手腕个人的学习记录,时间在12月13日 ~ 12月14日,学习方式看官方文档和B站视频,如有错误或者代码问题的地方,欢迎C站大佬能够帮忙指正一下(我是小白,瑟瑟发抖)

官方文档地址:Node.js 官方参考文档

1、Node.Js 基础介绍

Node.js 可以解析JS代码(没有浏览器安全级别的限制)提供很多系统级别的API,文件的读写 (File System),进程的管理 (Process),网络通信 (HTTP/HTTPS)

1.1、网络通信请求

const https = require('http')https.get('http://localhost:8080/index', (res) => {console.log(res) // 返回的是对象let str = ''res.on('data',(chunk)=>{str += chunk})res.on('end',()=>{console.log(JSON.parse(str))})})

创建接口

const http = require("http")http.createServer((req,res) => {res.writeHead(200, {"content-type": "text/plain"})res.write("hello nodejs!")res.end()}).listen(3000)console.log("http://localhost:3000")

打开浏览器:http://localhost:3000,展示如下

创建3000端口监听

const http = require("http")http.createServer((req,resp) => {let url = req.urlresp.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});if(url == "/index"){let arr = ["apple","banana","orange"]resp.write(JSON.stringify(arr))} else if (url == "/main") {resp.write("你访问了主页")} else {resp.write("你访问的页面不存在,404")}resp.end()}).listen(3000)

resp.writeHead(200, {‘Content-Type’: ‘text/plain; charset=utf-8’}); 设置响应头,设置字符集编码,防止返回乱码。

输出的内容:

1.2、文件读写

const fs = require('fs')fs.writeFile('log.txt','hello', (err , data) => {if(err){console.log("file create sorry!")} else {console.log("file create successfully")}})

1.3、进程的管理

function main(argv) {console.log(argv)}main(process.argv.slice(2))

控制台输出:

function main(argv) {console.log(argv)}main(process.argv)

控制台输出:

2、Node.Js 相关工具

2.1、版本查询方法

npm view 包名pkg versions:查看服务器上包pkg的最新的版本信息npm ls 包名pkg -g:查看本地全局安装的pkg版本npm info 包名pkg:查看npm js服务器上包pkg的最新的版本信息,比npm view pkg version提供的信息更丰富

版本号:x.x.x

例如:5.2.3 主版本号 major:5 次版本号 minor:2 补丁号 patch:3

patch是奇数的话是不稳定的版本,如果是偶数的话则是稳定的版本

npm outdated:查看过期的包信息

^ x.x.x:锁定主版本号,其他取最新;

~ x.x.x:锁定主版本和次版本号,其他取最新;

x.x.x:锁定主次补丁版本号;

2.2、npm 内置包

const path = require('path')console.log(__dirname);// resolve 路径的解析console.log(path.resolve(__dirname, '../'))

2.3、npm 第三方包

-y: 所有的操作提示全部yes-g: 全局进行安装对应的包

使用npm下载第三方包,例如:axios,来请求调用网易接口

接口地址:/api/rand.music?type=json&sort=热歌榜

const axios = require('axios')axios.get("/api/rand.music?type=json&sort="+encodeURI("热歌榜")).then(res => {console.log(res)}).catch(err => {console.error(err); })

nodejs使用axios进行http get请求时,报错TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters,其出现的原因是请求的url中携带中文参数。

解决方案:“/api/rand.music?type=json&sort=”+encodeURI(“热歌榜”)

下载lodash第三方包,测试如下:

const _ = require('lodash')let arr = [1,2,3,4,5,6]let double_arr = _.chunk(arr,2)console.log(double_arr)

输出的结果:

2.4、npm 自定义包

const _ = require("lodash")module.exports = function mychunk(arr){return _.chunk(arr,2)}// 使用测试const mychunk = require('./mychunk')let test_arr = [2,4,6,8]console.log(mychunk(test_arr))

测试结果:

2.5、npm 发布自定义包

查看npm源:npm config get registry

切换npm源方法一:npm config set registry

切换npm源方法二:nrm use npm

PS C:\Users\16204\Desktop\Nodejs> npm addusernpm notice Log in on /Username: wristwakingPassword:Email: (this IS public) 1620444902@

上传的命令:npm publish

如果上传失败,检查包的名称,在package.json文件中修改name属性,原因是你的包名在npm已经存在。

2.6、npm 脚本

如果是并行执行(即同时的平行执行),可以使用 & 符号。

$ npm run script1 & npm run script2

如果是继发执行(即只有前一个任务成功,才执行下一个任务),可以使用 && 符号。

$ npm run script1 && npm run script2

常用的 npm 脚本简写形式:npm start 是 npm run start

npm 脚本有一个非常强大的功能,就是可以使用 npm 的内部变量。

首先,通过 npm_package_ 前缀,npm 脚本可以拿到 package.json 里面的字段。比如,下面是一个 package.json。

{"name": "foo", "version": "1.2.5","scripts": {"view": "node wrist.js"}}

// wrist.jsconsole.log(process.env.npm_package_name); // fooconsole.log(process.env.npm_package_version); // 1.2.5

npmpackage前缀也支持嵌套的package.json字段。

上面代码中,我们通过环境变量 process.env 对象,拿到 package.json 的字段值。如果是 Bash 脚本,可以用$npm_package_name 和 $npm_package_version 取到这两个值。

"repository": {"type": "git","url": "xxx"},scripts: {"view": "echo $npm_package_repository_type"}

在window操作系统中:“echo %npm_package_repository_type%”

在Linux操作系统中:“echo $npm_package_repository_type”

2.7、npm 安装 Git 包

这样适合安装公司内部的git服务器上的项目

npm install git+https://git@:lurongtao/gp-project.git

或者以ssh的方式

npm install git+ssh://git@:lurongtao/gp-project.git

2.8、nrm 镜像源

NRM (npm registry manager)是npm的镜像源管理工具,有时候国外资源太慢,使用这个就可以快速地在 npm 源间切换。

查看当前源

npm config get registry

切换淘宝源

npm config set registry https://registry.

安装 nrm:在命令行执行命令,npm install -g nrm,全局安装nrm

使用 nrm:执行命令 nrm ls 查看可选的源。 其中,带*的是当前使用的源,上面的输出表明当前源是官方源。

切换 nrm:如果要切换到taobao源,执行命令nrm use taobao。

测试速度:你还可以通过 nrm test 测试相应源的响应时间。

2.9、npx 扩展小工具

NPX: npm package extention

npm 从5.2版开始,增加了 npx 命令。Node 自带 npm 模块,所以可以直接使用 npx 命令。万一不能用,就要手动安装一下。

主要作用1:调用项目安装的模块

npx 会自动查找当前依赖包中的可执行文件,如果找不到,就会去 PATH 里找。如果依然找不到,就会帮你安装!

npm install -g npx

npx 想要解决的主要问题,就是调用项目内部安装的模块。比如,项目内部安装了Mocha。

npm install -D mocha

一般来说,调用 Mocha ,只能在项目脚本和 package.json 的scripts字段里面,如果想在命令行下调用,必须像下面这样。

# 项目的根目录下执行node-modules/.bin/mocha --version

npx 就是想解决这个问题,让项目内部安装的模块用起来更方便,只要像下面这样调用就行了。

npx mocha --version

npx 的原理很简单,就是运行的时候,会到node_modules/.bin路径和环境变量$PATH里面,检查命令是否存在。

主要作用2:避免全局安装模块

除了调用项目内部模块,npx 还能避免全局安装的模块。比如,create-react-app 这个模块是全局安装,npx 可以运行它,而且不进行全局安装。

npx create-react-app my-react-app

上面代码运行时,npx 将 create-react-app 下载到一个临时目录,使用以后再删除。所以,以后再次执行上面的命令,会重新下载 create-react-app。

注意,只要 npx 后面的模块无法在本地发现,就会下载同名模块。比如,本地没有安装http-server模块,下面的命令会自动下载该模块,在当前目录启动一个 Web 服务。

npx http-server

3、模块 / 包 与 Common.JS

前端模块化:

AMD( require.js)CMD( sea.js )Common.Js( module.export / require )ES6 模块化( export / import )

3.1、模块化的区别

Common.Js:主要实践者为 Node.Js

1、commonjs模块输出的是值的拷贝,被模块缓存,在另一个模块可以修改赋值,当输出的是基本数据类型的时候,修改时不会影响到相应模块的值,当输出的是引用类型的值时,此时是浅拷贝,共享一个对象的地址,修改时会影响其他相关模块中的值。

2、当使用require命令加载某个模块时,就会运行整个模块的代码。当使用require命令加载同一个模块时,不会再执行该模块,而是取到缓存之中的值。也就是说,Commonjs模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。

3、循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

ES6

1、输出的是动态只读引用, 在import一个模块时,会生成一个只读引用,不能进行修改。当执行需要用到该值时,才会根据只读引用去原模块中取值。如果在原模块中修改值,所有用到该值的模块中的引用值都会修改。

2、循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行。

3.2、模块 / 包 分类

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

内置的模块

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

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

第三方的 Node.js 模块

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

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

自定义的Node.js模块

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

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

const name = {username: '唤醒手腕',sayName() {console.log(this.username)}}const age = {age: 100}module.exports = {name,age}## 测试const {name,age} = require("./app")name.sayName()console.log(age.age)

日常问题,案例:

const export = module.exportsexport = {name , age }## 运行失败:

原因:export原来的引用是module.exports,重新赋值{ name , age },引用被打破。

4、常用内置模块

这里介绍几个常用的内置模块:url, querystring, http, events, fs, stream, readline, crypto, zlib

4.1、内置模块 url

const url = require('url');const urlString = ':443/path/index.html?id=2#tag=3'console.log('show:', url.parse(urlString))## 结果:show: Url {protocol: 'https:',slashes: true,auth: null,host: ':443',port: '443',hostname: '',hash: '#tag=3',search: '?id=2',query: 'id=2',pathname: '/path/index.html',path: '/path/index.html?id=2',href: ':443/path/index.html?id=2#tag=3'}

const url = require('url')url.resolve('/', 'one')// /oneurl.resolve('/', '/one')// /oneurl.resolve('/one', '/two')// /two

4.2、内置模块 log4js

const log4js = require('log4js');var logger = log4js.getLogger();logger.level = 'debug';logger.debug('this is a debug log');

const log4js = require("log4js");log4js.configure({appenders: {cheese: {type: "file", filename: "cheese.log" } },categories: {default: {appenders: ["cheese"], level: "error" } }});const logger = log4js.getLogger("cheese");logger.trace("Entering cheese testing");logger.debug("Got cheese.");logger.info("Cheese is Comté.");logger.warn("Cheese is quite smelly.");logger.error("Cheese is too ripe!");logger.fatal("Cheese was breeding ground for listeria.");

4.3、内置模块 http / https

const http = require('http')const server = http.createServer((req,resp) => {console.log('req = ', req)resp.end()})server.listen(3000, () => {console.log('http://localhost:3000')})

4.4、跨越解决方案 CORS

4.5、跨域解决方案 JSONP

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": "唤醒手腕"})`)breakdefault:res.end('404.')break}})app.listen(8080, () => {console.log('localhost:8080')})

4.6、内置模块 fs

文件夹的操作,文件的基本读写操作

const fs = require("fs")fs.mkdir('log',(err)=>{console.log('create successfully', '')})fs.rename('log','newdir',()=>{console.log('rename successfully', '')})fs.rmdir('newdir',()=>{console.log('remove dir successfully', '')})fs.readdir('log',(err, files)=>{console.log(files)})// 写文件fs.writeFile('./log/test.txt','hello wristwaking',()=>{console.log('write txt successfully', '')})// 追加写入fs.appendFile('./log/test.txt','new world',()=>{console.log('append txt successfully', '')})// 读文件fs.readFile('./log/helloword.txt',(err,data)=>{console.log('data:', data.toString())})fs.readFile('./log/helloword.txt','utf-8',(err,data)=>{console.log('data:', data)})// remove filefs.unlink('./log/test.txt',()=>{console.log('delete file successfully', '')})

关于文件读写的同步方法代码

const fsPromise = require('fs/promises')data = fsPromise.readFile('./log/helloword.txt') newdata = data.then((result)=>{console.log('tag', result.toString())})console.log('newdata = ', newdata)

批量的写入文件的方式

// 批量写文件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'))})})})

文件流的读写操作 / 文件压缩

const fs = require('fs')const zlib = require('zlib')const gzip = zlib.createGzip()const readStream = fs.createReadStream('./log/helloword.txt')const writeStream = fs.createWriteStream('./log/helloword2.txt')readStream.pipe(gzip).pipe(writeStream)

4.7、实现爬虫功能 cheerio

选取网页url,使用http协议get到网页数据

豆瓣TOP250链接地址:/top250

首先我们请求http协议,通过http来拿到网页的所有数据

const https = require('https');https.get('/top250',function(res){// 分段返回的 自己拼接let html = '';// 有数据产生的时候 拼接res.on('data',function(chunk){html += chunk;})// 拼接完成res.on('end',function(){console.log(html);})})

上面代码呢,大家一定要注意我们请求数据时,拿到的数据是分段拿到的,我们需要通过自己把数据拼接起来

res.on('data',function(chunk){html += chunk;})

拼接完成时 我们可以输出一下,看一下我们是否拿到了完整数据

res.on('end',function(){console.log(html);})

二、使用cheerio工具解析需要的内容

const cheerio = require('cheerio');res.on('end',function(){console.log(html);const $ = cheerio.load(html);let allFilms = [];$('li .item').each(function(){// this 循环时 指向当前这个电影// 当前这个电影下面的title// 相当于this.querySelector const title = $('.title', this).text();const star = $('.rating_num',this).text();const pic = $('.pic img',this).attr('src');// console.log(title,star,pic);// 存 数据库// 没有数据库存成一个json文件 fsallFilms.push({title,star,pic})}}

下面就是保存数据了,我将数据保存在 films.json 文件中 将数据保存到文件中,我们引入一个fs模块,将数据写入文件中去

const fs = require('fs');fs.writeFile('./films.json', JSON.stringify(allFilms),function(err){if(!err){console.log('文件写入完毕');}})

源码展示:

// 请求 url - > html(信息) -> 解析htmlconst https = require('https');const cheerio = require('cheerio');const fs = require('fs');// 请求 top250// 浏览器输入一个 url, gethttps.get('/top250',function(res){// console.log(res);// 分段返回的 自己拼接let html = '';// 有数据产生的时候 拼接res.on('data',function(chunk){html += chunk;})// 拼接完成res.on('end',function(){console.log(html);const $ = cheerio.load(html);let allFilms = [];$('li .item').each(function(){// this 循环时 指向当前这个电影// 当前这个电影下面的title// 相当于this.querySelector const title = $('.title', this).text();const star = $('.rating_num',this).text();const pic = $('.pic img',this).attr('src');// console.log(title,star,pic);// 存 数据库// 没有数据库存成一个json文件 fsallFilms.push({title,star,pic})})// 把数组写入json里面fs.writeFile('./films.json', JSON.stringify(allFilms),function(err){if(!err){console.log('文件写入完毕');}})// 图片下载一下downloadImage(allFilms);})})function downloadImage(allFilms) {for(let i=0; i<allFilms.length; i++){const picUrl = allFilms[i].pic;// 请求 -> 拿到内容// fs.writeFile('./xx.png','内容')https.get(picUrl,function(res){res.setEncoding('binary');let str = '';res.on('data',function(chunk){str += chunk;})res.on('end',function(){fs.writeFile(`./images/${i}.png`,str,'binary',function(err){if(!err){console.log(`第${i}张图片下载成功`);}})})})}}

传统的request方式,封装请求到html数据。

5、Node.Js 连接数据库

5.1、连接 MySQL 数据库

两种方式:1. 基本连接数据库;2. 采用Pool连接池技术连接数据库

基本连接数据库

const mysql = require('mysql')console.log('mysql: ', mysql)const DataBaseConfig={host:"localhost",user:"root",password:"root",port:"3306",database:"nodedb" }let connect = mysql.createConnection(DataBaseConfig)//开始链接数据库connect.connect(function(err){if(err) {console.log(`mysql连接失败: ${err}`);} else {console.log("mysql连接成功");}});const Sql_Query = 'select * from people'connect.query(Sql_Query, function(err, result) {console.log(result);closeMysql(connect)});//查询成功后关闭 mysqlfunction closeMysql(connect){connect.end((err)=>{if(err){console.log(`mysql关闭失败:${err}`);}else{console.log('mysql关闭成功');}});}

采用Pool连接池技术连接数据库

通过连接池createPool()方法连接数据库的方式与通过createConnection()方法用法一致;然后通过getConnection()方法来对数据库进行连接,release()释放连接池中的数据库连接。

注意只是单纯的释放并没有关闭,如果有下次对数据库的访问还是会用上的;pool.end()方法是关闭连接池,完全关闭可以理解为对数据库的完全关闭;

let mysql = require("mysql");const db_config={host:"localhost",user:"root",password:"root",port:"3306",database:"nodedb" }let pool = mysql.createPool(db_config);pool.getConnection(function(err , connect){// 通过getConnection()方法 进行数据库连接if (err) {console.log(`mysql链接失败 : ${err}`);} else {connect.query('select * from people', function(err , result){if (err) {console.log(`SQL error : ${err}`)} else {console.log(result);connect.release();// 释放连接池中的数据库连接pool.end();// 关闭连接池}});}});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。