nodeJs

1.概述

1.1介绍

Node.js是一个内置有chrome V8引擎的JavaScript运行环境,他可以使原本在浏览器中运行的JavaScript有能力跑后端,从而操作我们数据库,进行文件读写等。

1.2下载和安装

下载地址:https://nodejs.org/zh-cn/download/。以往的版本:https://nodejs.org/zh-cn/download/releases/

选择合适的版本,然后直接安装即可。

安装好后,打开cmd,输入node,出现下面显示的信息,说明安装成功,执行两次ctrl+C退出node命令。

 

1.3运行js文件

新建index.js文件,内容如下:

console.log('hello world')

在cmd切换到index.js所在的目录,执行node index.js即可看到输出的信息。因此只需要通过node命令即可运行对应的js文件。

2.npm常用的命令

npm -v:查看npm版本。
npm init:初始化后会出现一个package.json配置文件。可以在后面加上-y,快速跳过问答式界面。
npm install:会根据项目中的package.json文件自动下载项目所需的全部依赖。
npm install包名 -D:安装的包只用于开发环境,不用于生产环境,会出现在package.json文件中的devDependencies属性中。
npm install 包名 -S:安装的包需要发布到生产环境的,会出现在package.ison文件中的dependencies属性中。
npm list:查看当前目录下已安装的node包。
npm list -g:查看全局已经安装过的node包。
npm --help:查看npm帮助命令。
npm update 包名:更新指定包。
npm uninstall 包名:卸载指定包。
npm config list:查看配置信息。
npm 指定命令 --help:查看指定命令的帮助。
npm info 指定包名:查看远程npm上指定包的所有版本信息。
npm config set registry https://registry.npm.taobao.org :修改包下载源,此例修改为了淘宝镜像。
npm root:查看当前包的安装路径。
npm root -g:查看全局的包的安装路径。
npm ls包名:查看本地安装的指定包及版本信息,没有显示empty。
npm ls包名 -g:查看全局安装的指定包及版本信息,没有显示empty。

2.1安装cnpm

由于npm比较慢,有时可以使用cnpm去安装依赖。下面是安装cnpm,并指定是淘宝镜像:

npm install -g cnpm -registry=https://registry.npm.taobao.org

3.文件系统fs

3.1文件的导入与导出

js中不可能只使用一个js文件,可能会需要其他js文件的值,就可以进行导入和导出。

新建test1.js,内容如下

var a=10;
var b=2;

新建test2.js,内容如下

var c=30;
console.log(a+c)

此时在test2中使用了test1的变量值,按照上例是无法获取到的,需要导入与导出。

test1.js修改:

var a=10;
var b=2;
//把a导出
exports.a=a

test2.js修改

var c=30;
//导出需要的对象,可省略后缀名,./代表当前目录下
var a = require('./test1')
console.log(a) //{ a: 10 }
console.log(a.a+c) //40

在没有任何内容导出去的情况下获取某个文件的内容,会得到一个空对象。

module.exports是模块导出,和exports的功能一样,原因是系统会把module.exports的值赋给exports,即exports=module.exports,但是他们还是有区别的,module.exports可以导出对象,而exports只能导出单个属性。

实例:调用其他js中的方法

test.js内容如下:

function test1(){
    console.log(123)
}
function test2(){
    console.log(456)
}
//导出两个方法
module.exports = {
  test1:test1,
  test2:test2
}

index.js内容如下:

//导入js
var tests=require('./test')
//调用方法
tests.test1()
tests.test2()

3.2使用第三方文件

jquery为例,首先要下载jquery的包,然后才能引入并使用。

1)在对应的目录执行下载命令

npm install jquery

2)js中引入并使用

var $ = require('jquery') 
console.log($)  

3.3require加载包规则

实际上在下载后,会在当前目录生成一个node_module的文件夹,里面就存放的是jquery相关的包。而在引入的时候,就会去node_module查找package.json文件,在这个文件里面找到mainmain对应的值就是jquery.js的位置,流程如图

其他规则:

如果在要加载的第三方包中没有找到package.json文件或者是package.json文件中没有main属性,则默认加载第三方包中的index.js文件。

如果在加载第三方模块的文件的同级目录没有找到node_modules文件夹,或者以上所有情况都没有找到,则会向上一级父级目录下查找node_modules文件夹,查找规则如上一致。

如果一直找到该模块的磁盘根路径都没有找到,则会报错:can not find module xxx。

3.4文件的读取

1)导入文件模块

//导入fs模块
var fs = require('fs')

2)同步读取文件,同步读取会降低效率,后面只介绍异步的

//同步读取文件
var cont = fs.readFileSync('hello.txt', {
    flag: 'r',//只读
    encoding: 'utf-8',//指定读取的编码
})
console.log(cont)

3)异步方式读取

//异步的读取
fs.readFile('hello.txt', {
    flag: 'r',//只读
    encoding: 'utf-8',//指定读取的编码
}, (err, data) => {
    if (err) {
        //发生错误
        console.log(err)
    } else {
        console.log(data)
    }
})

4)对异步的方式进行封装

//对异步的方式进行封装
function fsRead(path) {
    return new Promise((resolve, reject) => {
        fs.readFile(path, {
            flag: 'r',//只读
            encoding: 'utf-8',//指定读取的编码
        }, (err, data) => {
            if (err) {
                reject(err)
            } else {
                resolve(data)
            }
        })
    })
}

5)使用封装的方法

//调用封装的读取文件的方法
fsRead('hello.txt').then(res=>{
    console.log("内容是:"+res)
},err=>{
    console.log(err)
})

6)文件的写入

var context='你好啊,七夕节快乐,年轻人'
//异步写入,指定的文件不存在时会自动创建
fs.writeFile('hello.txt',context,{
    flag: 'w',//写,w会覆盖原内容,a在后面追加
    encoding: 'utf-8',//指定读取的编码
},err =>{
    if(err){
        console.log('发生错误')
    }else{
        console.log('写入成功') 
    }
})

7)对写入进行封装

//对异步的方式进行封装
function fsWrite(path,context) {
    return new Promise((resolve, reject) => {
        fs.writeFile(path,context, {
            flag: 'a',//写,w会覆盖原内容,a在后面追加
            encoding: 'utf-8',//指定读取的编码
        }, err => {
            if (err) {
                reject(err)
            } else {
                resolve()
            }
        })
    })
}

//调用

8)调用封装的方法

//调用封装的读取文件的方法
fsWrite('hello1.txt',context).then(res=>{
    console.log("成功")
},err=>{
    console.log(err)
})

3.5目录的读取

3.5.1读取目录

//读取目录下的文件
fs.readdir('hello',(err,files)=>{
    if(err){
        console.log(err)
    }else{
        files.forEach(file=>{
            console.log(file)
        })
    }
})

3.5.2删除目录

//删除目录
fs.rmdir('hello',{
    recursive:true,//递归删除目录,如果不指定则只能删除空目录
},err =>{
    if(err){
        console.log(err)
    }else{
        console.log('删除目录成功')

    }
})

3.6数据输入

有时候,需要从终端输入相关的信息,可以使用下面的例子

//数据输入
var readline=require('readline')
//指定从终端读取和输入内容
var rl=readline.createInterface({
    input:process.stdin,
    output:process.stdout
})

//发送请求
rl.question('今晚吃的啥?',answer=>{
    console.log(answer)
    //输入完成后就关闭
    rl.close()
})
//关闭时结束进程
rl.on('close',()=>{
    process.exit(0)
})

4.流Stream

4.1介绍

它是一个抽象接口,Node 中有很多对象实现了这个接口。对于大文件,使用普通的写入和读取是不科学的,可以使用流方式进行。

表-流类型

全称

简写

说明

Readable

r

可读操作

Writable

w

可写操作

Duplex

d

可读可写操作

Transform

t

操作被写入数据,然后读出结果

Stream常用事件

data     当有数据可读时触发。
end     没有更多的数据可读时触发。
error     在接收和写入过程中发生错误时触发。
finish     所有数据已被写入到底层系统时触发。

4.2输入流

通过流的方式把数据写到文件中

var fs = require('fs')

//创建写入流
var ws = fs.createWriteStream('hello.txt')
//监听文件打开事件
ws.on('open', () => {
    console.log('文件已打开')
})
//监听数据写入完成事件
ws.on('finish', () => {
    console.log('数据写入完成')
})
//监听文件关闭事件
ws.on('close', () => {
    console.log('文件已关闭')
})
//写入数据
ws.write('你好啊,情人节', err => {
    if (err) {
        console.log(err)
    }
})
//关闭流
ws.end()

后期对于流操作时,文件的关闭和打开事件可不监听。

4.3输出流

把文件的内容通过流的方法读出来

var fs = require('fs')

var data = ''
//创建可读流
var rs = fs.createReadStream('hello.txt')
//监听文件打开事件
rs.on('open', () => {
    console.log('文件已打开')
})
//监听处理流事件
rs.on('data', chunk => {
    data += chunk
})
//监听流入结束事件
rs.on('end', chunk => {
    console.log(data)
})
//监听文件关闭事件
rs.on('close', () => {
    console.log('文件已关闭')
})

4.4管道

提供了一个输出流到输入流的机制即把读取的流放到输入流,写入文件,用起来非常方便。

//管道流
// 创建一个可读流
var readerStream = fs.createReadStream('hello.txt');
// 创建一个可写流
var writerStream = fs.createWriteStream('output.txt');
// 管道读写操作:读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);
console.log("复制完毕");

5.事件event

Node.js 是单进程单线程应用程序基本上所有的事件机制都是用设计模式中观察者模式实现

// 引入 events 模块
var events = require('events');
//创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter()
function connection(f) {
    console.log('我是connection方法,我被执行了' + f)
}
//绑定函数,指定事件的名称
eventEmitter.on('conn', connection)

//在某一时刻触发事件
setTimeout(function () {
    //触发事件并传递参数
    eventEmitter.emit('conn'123)
}, 2000); 

注册好的事件,等待某一时刻触发,就会执行注册的方法。

6.路径模块path

路径模块,主要的对文件的路径进行操作。下面的实例中,包含文件的扩展名、目录全路径、文件全路径以及路径解析等。

xar path = require('path')

var filePath="E://files/项目记录.txt"
//获取文件的扩展名
var extname = path.extname(filePath)
console.log(extname)//.txt
//获取当前目录的完整路径
var dirName=__dirname
console.log(dirName)//E:projectdemo
ode-demo
//获取当前执行文件的完整路径
var fileName=__filename
console.log(fileName)//E:projectdemo
ode-demopath.js
//路径拼接
var p1=path.join('C:','files','text','t1.html')//C:files	ext	1.html
console.log(p1)
//获取路径的所在目录路径
console.log(path.dirname(filePath))
//解析路径,返回的是一个对象,包含文件的基本信息
console.log(path.parse(filePath))

7.系统模块os

系统模块主要用来获取操作系统相关的参数

var os=require('os')

//获取操作系统的cpu信息
console.log(os.cpus())
//内存
console.log(os.totalmem())
//系统架构
console.log(os.arch())
//剩余内存
console.log(os.freemem())
//主机名
console.log(os.hostname())
//操作系统类型
console.log(os.platform())

8.网址url

网址模块主要用来解析url的相关信息

var url=require('url')
const { hostname } = require('os')

var httpUrl='https://baijiahao.baidu.com/s?id=1676038746523370835&wfr=spider&for=pc'
//把url进行格式化
var parseObj=url.parse(httpUrl)
console.log(parseObj)

格式化参数解析:

9.cheerio

cheerio是nodejs的抓取页面模块,为服务器特别定制的,快速、灵活、实施的jQuery核心实现。适合各种Web爬虫程序。

它不是nodejs自动的库,需要进行安装,命令是

npm i cheerio

9.1爬取网站的表情包

//需要安装,npm i cheerio
var cheerio =require('cheerio')
//需要安装,npm i axios
var axios = require('axios')
var fs = require('fs')
var path = require('path')

var httpUrl="https://www.doutula.com/photo/list/?page=2"

axios.get(httpUrl).then(res=>{
    //解析html文件
    var $ =cheerio.load(res.data)
    //获取图片的链接
    $("#pic-detail .list-group-item .page-content a").each((i,elem)=>{
        parseUrl($(elem).attr("href"))
    })
})
async function parseUrl(url) {
    //通过点击a标签去查询图片地址
    var res = await axios.get(url)
    var $ = cheerio.load(res.data)
    $(".pic-content .swiper-slide img").each((i, elem) => {
        var src=$(elem).attr("src")
        var title=$(elem).attr("alt")
        var extname=path.extname(src)
        var ws = fs.createWriteStream(`img/${title}${extname}`)
        axios.get(src,{responseType:'stream'}).then(res=>{
            res.data.pipe(ws)
        })
    })
}

在爬取的时候,通过流的方式保存文件,因此这请求时要指定响应类型为stream。

10.Puppeteer

10.1介绍

谷歌官方出品的一个通过DevTools协议控制headless Chrome的Node库。可以通过Puppeteer的提供的api直接控制Chrome模拟大部分用户操作来进行UI Test或者作为爬虫访问页面来收集数据。

作用:生成页面 PDF。抓取 SPA(单页应用)并生成预渲染内容。自动提交表单,进行 UI 测试,键盘输入等

中文文档:https://zhaoqize.github.io/puppeteer-api-zh_CN/#/

需要安装使用:

npm i puppeteer

10.2基本使用

下面的实例可以保存网页的部分截图,也能把网页信息保存为pdf

var puppeteer = require('puppeteer')
async function test() {
    var option={
        //headless为false是关闭headless模式,配置为有界面调试
        // headless: false ,
        //设置视窗的大小
        defaultViewport:{
            1920,
            height:1096
        }

    }
    //创建browser的实例
    const browser = await puppeteer.launch(option)
    //打开新页面
    const page = await browser.newPage()
    //访问页面
    await page.goto('https://www.cnblogs.com/zys2019/p/13323889.html')
    //把当前的页面截图保存
    await page.screenshot({ path: 'example.png' })
    //把当前页面保存为pdf,只能在headless为true时调用
    await page.pdf({path: 'example.pdf', format: 'A4'})
    //关闭浏览器实例
    await browser.close()
}
test()

11.http

开启一个本地服务器需要Node.js中http核心模块

var http = require('http')

//创建服务器对象
let server = http.createServer()
//监听服务的请求
server.on('request', (req, res) => {
    //req是请求的信息,res是响应信息
    var url = req.url//请求的url
    var header = req.headers//请求头信息
    //设置响应编码
    res.setHeader('Content-Type''text/plain; charset=UTF-8')
    //设置响应的信息
    res.end('hello world,你好')
})

//监听端口号,在启动服务时就触发
server.listen(3000, () => {
    console.log('服务器已启动')
})

启动后,使用本机ip+3000即可访问

12.node连接mysql数据库

需要安装后使用:

npm i mysql

连接数据库并操作

//引入模块
let mysql = require('mysql')

//配置连接参数
let options = {
    host: "localhost",
    user: "root",
    password: "zys123456",
    database: "db2020"
}
//创建连接
let conn = mysql.createConnection(options)

//连接到数据库
conn.connect(err => {
    if (err) {
        console.log('连接失败,错误:' + err)
    } else {
        console.log('连接成功')
    }
})

//执行sql语句,所有的操作都是使用query方法,里面传入sql即可
let sql = 'select * from user'
//查询数据,err是报错信息,results是查询结果,fields是数据库信息。
conn.query(sql, (err, results, fields) => {
    if (err) {
        console.log('查询失败,错误:' + err)
    } else {
        console.log(results)
    }
})

 .

就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
原文地址:https://www.cnblogs.com/zys2019/p/13567718.html