官方文档
常用的模块
promise 和 async
- 传统ajax
$.get(url,()=>{})
- promise
axios.get(url).then((res)=>{})
- async awiat
(async ()=>{let res = await get(url)})()
文件的io
- 参考api
- 封装成promise
const fs = require('fs')
// 封装promise
function AsyncReadFile(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, {
flag: 'r'
}, (err, data) => {
if (err) {
reject(err)
} else {
resolve(data.toString())
}
})
})
}
async function readList() {
var a1 = await AsyncReadFile('./utils.js')
}
readline
- 相当于python 的input()
- 参考 api
- 示例代码
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function readParams(ques) {
return new Promise((resolve, reject) => {
rl.question(ques, (answer) => {
resolve(answer)
});
})
}
async function InitParams() {
var q1 = await readParams('问题一')
var q2 = await readParams('问题二')
var q3 = await readParams('问题三')
console.log(q1, q2, q3)
}
事件
- 类似于 消息队列
- 内置 events 模块
- 示例代码
const FS = require('fs')
const EVENTS = require('events')
// 创建事件对象
var ee = new EVENTS.EventEmitter()
// 监听
ee.on('successFunc', (res) => {
console.log(res)
})
FS.readFile('./a.txt', (err, data) => {
if (err) {
} else {
// 触发事件
ee.emit('successFunc', data.toString())
}
})
path 处理文件与目录的路径
os 模块
url 模块 处理与解析 URL
- url.parse(url) 返回对象
- url.resolve(a,b) 拼接
axios 异步请求库
cheerio js的爬虫库
- 解析方式和jquery一样 api使用方式也和jquery相同
- 示例
var $ = cheerio.load(html)
$('#aaa b').each((i,ele)=>{
$(ele).attr('src')
})
puppeteer 谷歌新的无头浏览器 和webdriver一样,可以运行在linux
- github 搜
- 初始化浏览器
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch(); // launch({headless:false})
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
- 配置拦截掉谷歌请求
web服务器部分
内置的http模块
- 最基本的http服务器
let http = require('http')
var server = http.createServer()
// 这里只能写request
server.on('request', (request, response) => {
if (request.url == '/') {
response.end('首页')
} else {
response.end('helloworld')
}
})
// 监听端口
server.listen(8000, () => {
console.log('server is running on 8000')
})
使用框架流程
- 封装请求
- 匹配路由,模版渲染
- 静态文件返回
自己上传npm包
- 先需要注册npm
- 创建文件夹
- npm init 设置相关信息
- 本机登陆npm
- npm login
- 发布 npm publish
node链接mysql
- npm install mysql
- 文档
express node的web框架
-
全局安装脚手架 npm install -g express-generator@4
-
创建项目 express --view=ejs project
-
热更新工具 nodemon
- npm install -g nodemon
- 在package.json 修改 “start”: “nodemon ./app.js”,
- npm start
-
路由模式
-
字符串模式 /index
-
类字符串的正则模式
- /ab?cd 匹配abcd / acd
- /ab+cd 匹配 abcd abbcd abbbcd
- /ab*cd 匹配 ab开头cd结尾
-
路由传参
- /news/:id
- 接收 req.params
-
多个回调函数可以处理一条路由
app.get('/example/b', function (req, res, next) { console.log('the response will be sent by the next function ...') next() }, function (req, res) { res.send('Hello from B!') })
- 链式路由
app.route('/book') .get(function (req, res) { res.send('Get a random book') }) .post(function (req, res) { res.send('Add a book') }) .put(function (req, res) { res.send('Update the book') })
- 快速路由 将路由器创建为模块,在其中加载中间件功能
// birds.js在app目录中创建一个名为以下内容的路由器文件 var express = require('express') var router = express.Router() // middleware that is specific to this router router.use(function timeLog (req, res, next) { console.log('Time: ', Date.now()) next() }) // define the home page route router.get('/', function (req, res) { res.send('Birds home page') }) // define the about route router.get('/about', function (req, res) { res.send('About birds') }) module.exports = router // app.js 加载路由器模块 var birds = require('./birds') app.use('/birds', birds)
-
-
ejs 模版引擎
- 文档
- 声明使用ejs模版
//引用ejs app.set('views',"public"); //设置视图的对应目录 app.set("view engine","ejs"); //设置默认的模板引擎 app.engine('ejs', ejs.__express); //定义模板引擎
- view 中的 render
res.render('index.ejs', { results: Array.from(result), a1: '<h2>h2</h2>', a2: '<h2>h2</h2>', }, (err, html) => { // 回掉 console.log(html) })
- 变量渲染
<%- a1 %> // 解析 htnl <%= a2 %> // 不解析html
- for循环
<% for (i in results) { %> <span><%= results[i].name %></span> <br> <% } %>
- 判断
<% if (user) { %> <h2><%= user.name %></h2> <% } %>
- include
<ul> <% users.forEach(function(user){ %> <%- include('user/show', {user: user}); %> <% }); %> </ul>
-
请求参数的获取
- get请求 req.query
- post请求
- 需要在app.js app.use(express.urlencoded())
- application/x-www-form-urlencoded req.body
- multipart/form-data 文件上传
-
中间件 分为:应用层中间件、路由中间件、内置中间件、错误处理中间件和第三方中间件
- 1.应用层中间件
// - 在app.js设置 //匹配路由之前的操作 app.use(function(req,res,next){ console.log("访问之前"); next(); // 不执行next放行 会一直阻塞 });
- 2.路由中间件
// var router=express.Router(); router.use("/login", function (req, res, next) { console.log('路由中间件') next() }); router.post("/login", function (req, res, next) { }); router.get("/login", function (req, res, next) { });
- 3.内置中间件
express.static是Express的唯一内置中间件 express.static(root, [options]); 通过express.static我们可以指定要加载的静态资源 // 例如 在 public/images/256.jpg <img src="/images/265.jpg" alt="">
- 4.错误处理中间件
一般把错误处理的中间件放在app.js的最后 app.use(function (req, res) { res.render('404') // res.status(404).send("未找到指定页面"); }); // 错误处理中间件 熔断 暂时还不对 app.use(function (err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; res.status(err.status || 500); // res.render('error'); res.sendStatus(err.httpStatusCode).json(err); });
- 5.第三方中间件
例如 var cookieParser = require('cookie-parser'); app.use(cookieParser());
-
cookie
- 需要安装cookie中间件
- var cookieParser = require(‘cookie-parser’)
- app.use(cookieParser())
- 获取 req.cookies
- 设置 res.cookie(key,val,[options])
domain: 域名 name=value:键值对,可以设置要保存的 Key/Value,注意这里的 name 不能和其他属性项的名字一样 Expires: 过期时间(秒) maxAge: 最大失效时间(毫秒),设置在多少后失效 。 secure: 当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中才有效 Path: 表示 在那个路由下可以访问到cookie。 httpOnly:则通过程序(JS 脚本、applet 等)将无法读取到COOKIE 信息,防止 XSS 攻击的产生 。 singed:表示是否签名cookie, 设为true 会对这个 cookie 签名, 这样就需要用 res.signedCookies 而不是 res.cookies 访问它。 被篡改的签名 cookie 会被服务器拒绝,并且 cookie 值会重置为它的原始值。
- 需要安装cookie中间件
-
加密 cookie
- 使用内置
- 配置中间件 app.use(cookieParser(‘secret’))
- 设置加密cookie res.cookie(“key”, “val”, {signed: true})
- 获取 req.signedCookies
- node内置 crypto md5
- 使用内置
-
session
- 使用
- 安装 npm install express-session --save - 导入 const session=require("express-session") - 配置中间件 app.use( session({ secret: "keyboard cat", // 随便设置 resave: false, // 是否持久化 saveUninitialized: true, // 是否保存初始化的session // 默认cookie:{} 只在当前绘画有效 cookie: ("name", "value", { maxAge: 5 * 60 * 1000, secure: false }), }) ); // api req.session.userinfo='张三'; //设置session //注销session req.session.destroy(function(err){ res.send("退出登录!"+err); }); req.session.userinfo //获取session
-
文件上传
-
常用 multer
-
npm install multer --save
-
上传单一文件
const multer = require('multer'); //初始化上传对象 var upload = multer({ dest: './upload/' }); var fs = require('fs'); // image 对应了input 的name属性 router.post('/add', upload.single("image"), function (req, res, next) { var oldFile = req.file.destination + req.file.filename; //指定旧文件 var newFile = req.file.destination + req.file.originalname; //指定新文件 fs.rename(oldFile, newFile, function (err) { if (err) { res.send('上传失败!'); } else { res.send('上传成功!'); } }); });
- 上传多个文件
配置 upload .single(fieldname) //接受一个以 fieldname 命名的文件。.fields(fields) .array(fieldname[, maxCount]) //maxCount 来限制上传的最大数量。 .fields(fields) // router.post("/add_mul", upload.array("images", 5), function (req, res, next) { req.files.forEach(function (ele, index) { console.log(ele); var oldFile = ele.destination + ele.filename; //指定旧文件 var newFile = ele.destination + ele.originalname; //指定新文件 fs.rename(oldFile, newFile, function (err) { err ? console.log('上传失败!') : console.log('上传成功!'); }); }); res.send("成功上传"); });
- 通过limits来限制上传文件
//初始化上传对象 var upload = multer({ dest: './upload/', limits: { fileSize: 1024, files: 5 } }); fieldNameSize field 名字最大长度 100 bytes fieldSize field 值的最大长度 1MB fields 非文件 field 的最大数量 无限 fileSize 在 multipart 表单中,文件最大长度 (字节单位) 无限 files 在 multipart 表单中,文件最大数量 无限 parts 在 multipart 表单中,part 传输的最大数量(fields + files) 无限 headerPairs 在 multipart 表单中,键值对最大组数 2000 // 可以使用err.code定位到该错误 LIMIT_PART_COUNT LIMIT_FILE_SIZE LIMIT_FILE_COUNT LIMIT_FIELD_KEY LIMIT_FIELD_VALUE LIMIT_FIELD_COUNT LIMIT_FIELD_COUNT router.use(function (err, req, res, next) { if (err.code === 'LIMIT_FILE_SIZE') { res.send('File is too large'); } else if (err.code === 'LIMIT_FILE_COUNT') { res.send('Too many files'); } })
- ajax 上传文件
var file = $('#iamges')[0].files[0] var Obj = new FormData() Obj.append("image", file) Obj.append("username", "张三") $.ajax({ url: 'http://localhost/uploads/add', type: 'post', data: Obj, processData: false, // 告诉jQuery不要去处理发送的数据 contentType: false, // 告诉jQuery不要去设置Content-Type请求头 dataType: 'json', success: function (res) { console.log(res); } })
-
-
允许跨域
// app.js设置
app.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
//Access-Control-Allow-Headers ,可根据浏览器的F12查看,把对应的粘贴在这里就行
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Methods', '*');
res.header('Content-Type', 'application/json;charset=utf-8');
next();
});
- 文件下载
router.get('/download', function (req, res, next) {
var name = req.query.name
res.download("./upload/" + name, err => {
if (err) {
res.send("下载失败!");
} else {
console.log("下载成功!");
}
})
});