node.js
作用:写webAPI 写中间层 前端工程化的一些(webpack,gulp)的基础
优势:性能高,便于前端入手
-
谈谈对Node的理解?
Node.js 在浏览器外运行V8 JavaScript引擎,单线程 非阻塞I/O 事件驱动,适应于数据高并发,适合多请求,但不适合高运算,有权限读取操作系统级别的API,无法直接渲染静态页面,提供静态服务,没有根目录的概念,必须通过路由程序指定文件才能渲染文件,比其他服务端性能更好,速度更快,npm 仓库,常用框架:Express,koa,Socket.io,AdonisJs,NestJS
-
如何判断当前脚本运行在浏览器还是node环境中?
this === window ? ‘browser’ : ‘node’,通过判断Global对象是否为window,如果不为window,当前脚本没有运行在浏览器中
-
node.js有哪些常用模块
-
get post区别
1.语义是获取,get携带参数的方式是querystring,在地址栏后直接拼接,不在请求体,理论上携带数据无限,但是浏览器地址栏有限,一般2kb,会被浏览器主动缓存,明文发送,只能发送url编码的数据即ASCII码,如果是中文会自动转码
2.语义是给,post携带参数是requestBody,在地址栏中没有,在请求体中,理论上无限,但是会被服务器限制,不会被浏览器主动缓存,暗文发送,理论上可以发送任意类型的数据,但是要和请求体的content-type配套
node安装
cmd键入cd 或者 shift+右键=>powershell窗口直接到当前目录下
cls 清空屏幕
cd 进入
.exit 退出 ctrl+c退出当前终端
node 进入node命令行
node a.js node a
node -v 查看版本号
npm包管理
npm -v
npm init
npm install xxx npm i xxx
--save
安装并添加条目到package.json
文件的 dependencies。--save-dev
安装并添加条目到package.json
文件的 devDependencies。
区别主要是,devDependencies
通常是开发的工具(例如测试的库),而 dependencies
则是与生产环境中的应用程序相关
npm uninstall npm un xxx
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm i xxx
cnpm un xxx
npm update xxx
npm i
全局安装:npm install express -g
本地安装:npm install express
npm list -g 查看所有全局安装的模块
nrm
开发的npm registry 管理工具 nrm, 能够查看和切换当前使用的registry
nrm ls // 查看所有的支持源(有*号的表示当前所使用的源,以下[name]表示源的名称)
nrm use [name] // 将npm下载源切换成指定的源
nrm test npm // 测试响应时间,检查网络延迟
package.json 常见属性
位于模块的目录下,用于定义包的属性,它记录了有关发布到 NPM 之前所需要的项目的重要元数据,它还定义了 npm 用于安装依赖项、运行脚本以及标识包的入口点的项目功能属性。
name version license author description keywords main他的值通常是项目根目录下的index.js文件 scripts repository dependencies他列出了所有依赖项
node模块
1.全局模块
process.env 环境变量
process.env.NODE_ENV // "development"
process.argv
// console.log(process.argv);
let num1=parseInt(process.argv[2]);
let num2=parseInt(process.argv[3]);
console.log(num1+num2);
2.内置模块
HTTP模块(核心)
http模块用于创建一个能够处理和响应http响应的服务
// 专门创建服务器对象,返回值一个HTTP服务
http.creatServer(fucntion(req,res){
})
// 服务.listen(端口号,回调函数)
server.listen(8080,()=>console.log('heelo'))
// 当监听完毕时,cmd窗口运行后,你的cmd窗口因为这段代码就变成了一个服务器,此时当客户端请求localhost:8080的时候,每一个请求都会触发一次create server的时候的函数,req本次请求的所有请求信息,res将来被组装为响应报文的东西
在index.js中require载入模块,最后效果localhost:8888/1.html可以访问
let http=require('http');
let fs=require('fs');
http.createServer((req,res)=>{
console.log(req.url);
fs.readFile(`./${req.url}`,(err,data)=>{
if(err){
// console.log(err);
res.writeHead(404);
res.end('404 not found')
}else {
res.end(data)
}
})
// res.write('index');
// res.end('index')
// console.log('hello');
}).listen(8888)
设置响应头,Content-type就是用来告诉对方我给你发送的数据内容是什么类型
参数1:必选,三位数的http状态码
参数2:可选,可有可无
参数3:可选,告诉浏览器我发给你的数据是什么类型的
res.writeHead(200, { 'Content-type': 'text/html;charset=utf-8' })
文件系统fs
内置的一个模块,该模块提供了用于与文件系统进行交互的API,并且所有的文件操作都具有同步和异步的形式。异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)
// 导入文件系统模块
var fs = require("fs")
...
// 异步模式下
// 打开文件
fs.open(path, flags[, mode], callback)
fs.open(path, flags[, mode], function(err,fd){})
// 获取文件信息
fs.stat(path, function(err,stats){
console.log(stats.isFile()); //检测文件类型,如果是文件,返回true
})
// 写入文件,完全覆盖的写入
fs.writeFile(file, data[, options], callback)
// 读取文件
fs.readFile(file, data[, options], callback)
// 读取文件
fs.read(fd, buffer, offset, length, position, callback)
// 关闭文件
fs.close(fd, callback)
// 截取文件
fs.ftruncate(fd, len, callback)
// 删除文件
fs.unlink(path, callback)
path内置模块
操作和路径相关的内容
const path=require('path')
...
// 专门获取一个路径的后缀名
path.extname('文件名')
// 判定是不是绝对路径,返回布尔值
path.isAbsolute('绝对路径')
路径表示方法:
test.js 同级目录下的
./test.js 同级目录下的
../test.js 上一级目录下的
/test.js 根目录下的
// 多个参数直接拼接相对路径,没有根目录这一说,任何一个地址都拼接在前一个后面
path.join()
require('path').join('/', 'users', name, 'notes.txt') //'/users/joe/notes.txt'
// 多个参数直接拼接为绝对路径,每一个参数位置都是相对于当前文件所在的目录设置的,/xxx直接返回到根目录
path.reslove('地址1','地址2',...)
path.resolve('tmp', 'joe.txt') //'/Users/joe/tmp/joe.txt' 如果从主文件夹运行
path.parse()// 返回值一个对象
url模块
const url=requrie('url')
// 返回值一个对象,包含这个URL的所有信息,第二个参数默认false不解析query
url.parse(url地址[, 是否解析query])
3.自定义模块
exports暴露了它指向的对象的属性
module.exports 暴露对象(类似class,包含了很多属性和方法)时使用
4.第三方模块
moment
专门处理时间的第三方模块,http://momentjs.cn/
npm i moment
const monent=require('moment')
mysql
npm init
npm i mysql
node .\mysql第三方模块.js
案例:
// 1.链接数据库,保证数据库的服务器确认开启
// 两种链接数据库的方法:
// creatConnect()偏向单次使用的语义,连接,操作,关闭
// createPool()偏向连接池的语义,连接,操作,操作,...
// mysql.creatConnect({配置信息})
// mysql.createPool({配置信息})
// 2.执行sql语句
// 使用连接信息去调用执行sql语句的方法
// 一个方法----执行不同的sql语句
// 语法:
// db.query(sql语句,回调函数)
// db.query(sql语句,数组,回调函数)
// sql语句中以问号的形式留下一些坑
// 数组里面的每一项去填坑
const mysql=require('mysql')
// 创建连接
const db=mysql.createConnection({
host:'localhost',
port:3306,
user:'root',
password:'123456',
database:'day17'
})
// 执行sql语句
const username='zhangsan'
const password='123'
const addSql='insert into user(id,name,gender,age,address,qq,email,username,password) values(4,?,?,?,?,?,?,?,?)'
const addSqlPar=['赵六','男',20,'江苏','123789','zhaoliu@123.com','zhaoliu','321']
// 查询
db.query('select * from `user` where `username`=? and `password`=?',[username,password],(err,data)=>{
if(err) return console.log(err);
console.log(data);
})
// 增加
db.query(addSql,addSqlPar,(err,info)=>{
if (err) return console.log(err);
console.log('---------------insert------------------');
console.log(info);
})
效果:
superagent()
专门用于node里面发送请求的第三方
cheerio()
专门把一段HTML文件解析为像jquery一样的函数的方法,cheerio实现了核心jQuery的子集,https://github.com/cheeriojs/cheerio/wiki/Chinese-README
const superagent = require('superagent')
const cheerio = require('cheerio')
const mysql = require('mysql')
const list = []
// 拿到HTML结构,data.text就是页面信息
// 把某些结构中的内容拿出来组装为一个对象
// 存储到数据库
superagent.get('https://list.jd.com/list.html?cat=670,671,672', (err, page) => {
if (err) return console.log(err);
parsePage(page.text)
})
// 创建连接
const db = mysql.createConnection({
host: 'localhost',
port: 3306,
user: 'root',
password: '123456',
database: 'day17'
})
function parsePage(page) {
const $ = cheerio.load(page)
$('ul.gl-warp>li').each(function (index, item) {
// item就是里面的每一个li
const obj = {
goods_img: $(item).find('.p-img img').prop('src'),
goods_price: $(item).find('.p-price i').text(),
goods_title: $(item).find('.p-name em').text(),
goods_name: $(item).find('.p-name i').text(),
}
// list.push(obj)
// 放到数据库中
const sql = 'insert into `jd_list` values(null,?,?,?,?)'
const info = [obj.goods_img, obj.goods_price, obj.goods_title, obj.goods_name]
db.query(sql, info, (err, data) => {
if (err) return console.log(err);
})
})
// console.log(list);
}
待解决:img的src没有填充进来?
数据交互
GET
GET主要是获取数据,数据在URL中进行传输,容量小<32k
由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括了?后面的部分,因此你可以手动解析后面的内容作为GET请求的参数。很好的是,node.js 中 url 模块中的 parse 函数提供了这个功能
url.parse(req.url,true)
let http = require('http');
let url = require('url');
// let util = require('util');
http.createServer((req, res) => {
let { pathname, query } = url.parse(req.url, true)
console.log(pathname, query);// aaa [Object: null prototype] { username: 'hehe', password: '123' }
// res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
// res.end(util.inspect(url.parse(req.url, true)));
}).listen(8888)
post
POST数据放在请求体中,容量大<2g
req.on('data',buffer=>{
arr.push(buffer)
})
req.on('end'.()=>{
Buffer.concat(arr).toString();// 实际用别人的模块
})
let http = require('http');
let querystring=require('querystring')
http.createServer((req, res) => {
let result=[];
req.on('data',(buffer)=>{
// console.log(buffer);// 二进制数据
result.push(buffer);
})
req.on('end',()=>{
// console.log(result);
let data=Buffer.concat(result).toString();// 这里只有用户名和密码才能用tostring,如果包含文件就不可以用
console.log(querystring.parse(data));// username=hehe&password=123 ----> { username: 'hehe', password: '1234' }
})
}).listen(8888)
var http = require('http');
var querystring = require('querystring');
var postHTML =
'<html><head><meta charset="utf-8"><title>菜鸟教程 Node.js 实例</title></head>' +
'<body>' +
'<form method="post">' +
'网站名: <input name="name"><br>' +
'网站 URL: <input name="url"><br>' +
'<input type="submit">' +
'</form>' +
'</body></html>';
http.createServer(function (req, res) {
// 定义了一个body变量,用来暂存请求体的数据
var body = "";
// 通过req的data事件监听函数,每当接收到请求体的数据时,就累加到post变量中
req.on('data', function (chunk) {
body += chunk;
});
// 在end事件触发后,通过querystring.parse将body解析为真正的POST请求格式,然后向客户端返回。
req.on('end', function () {
// 解析参数
body = querystring.parse(body);
// 设置响应头部信息及编码
res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});
if(body.name && body.url) { // 输出提交的数据
res.write("网站名:" + body.name);
res.write("<br>");
res.write("网站 URL:" + body.url);
} else { // 输出表单
res.write(postHTML);
}
res.end();
});
}).listen(3000);