为什么学nodejs,因为听说学会了nodejs可以做全栈开发,哈哈,我也是一个有野心的程序员(其实并没有)。
nodejs学了好几次,也放弃了好几次,主要原因就是感觉莫名其妙(自学),跟前端开发联系不上,光是环境搭建(Windows系统)就卡死了好几次,明明是跟着教学视频(自学失败几次后买了教学视频)一步步学的,就是没有人家的效果,时间长了就从入门到放弃,但既然买了课程,虽然实践不了,但我也强撑着把视频看完了,不然多浪费。
最近,我发现了一门合适的课程,重燃了我对nodejs学习的兴趣和信心,又发现了周边的一门课,也很好,简直是为我量身打造的,哈哈,狠狠心,花了五百多大洋(为此我还专门进行了深刻的反省,你说买件衣服一千多的不嫌贵,怎么买课程就小气了呢,不应该),买下了课程,付完款的那一刻我异常轻松和开心,哈哈,感觉就像已经学会了所买的课程似的。
这里要打个广告,慕课网付费好课程分享给大家(先说好,我是不会借账号的)。知识是需要付费的,尊重版权,尊重作者。另外,只有花费得来的东西,才会珍惜,才会认真。
买七月老师的小程序nodejs课程,是因为我前面看了配套的小程序开发课程,学了前端,正好补足后端。
双越老师的nodejhs博客项目是套餐推荐买的,我看了介绍,也挺合适,就一起买了。实践证明,一起买非常明智。先看的七月老师的课,呃,起点有点高,而且小程序我也不熟,看了几节课看不下去了,就去看双越老师的课,嗯,体验很好,渐进式学习,浏览器这边也比较熟悉(我是web前端),在学习中也可以及时弥补不足,相信等双越老师的课看完,再去看七月老师的课会顺畅点。
废话有点多,正文来了。本文主要目的是记录学习中遇到的问题及解决方法,方便以后忘记了可以查阅。
Node.js 概述
js运行环境--解释器 ;
服务器端语言,使用一种语言统一了前后端的开发;
使用ECMScript语法规范,提供nodejs API,可处理http,处理文件等;
没有BOM和DOM对象 ;
可以在终端使用(命令行),node 进入--输入js代码,回车执行(使js脱离了浏览器可以运行),也可以执行js文件。
环境准备(Mac os 系统)
下载brew
to install Homebrew,paste that in a macOS Terminal prompt.
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
下载nvm
不同项目使用的nodejs的版本可能不一样,使用nodejs的版本管理工具 nvm 可以切换多个nodejs版本。
安装nvm
brew install nvm
安装完成后使用 nvm list 查看当前所有的node版本,提示命令不可用,先卸载吧,暂时也用不上。
brew uninstall nvm
下载nodejs
https://nodejs.org/en/download/
nodejs安装后测试
node -v
npm
nodejs 自带npm,查看npm版本。
npm -v
新建一个项目时,在项目根目录,初始化npm的配置文件。
npm init -y
npm init 与 npm init [--force|-f|--yes|-y|--scope] 的区别:前面是交互式命令行,提示输入各种信息,后面的全都使用默认值。
搭建开发环境
下载nodemon
npm i nodemon cross-env --save-dev
使用nodemon 监测文件变化,自动重启node;
使用cross-env设置环境变量,兼容Mac Linux 和 window;
"dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js",
"prd": "cross-env NODE_ENV=production nodemon ./bin/www.js"
使用postman 模拟发送post请求
遇到的问题:获取不到postman发送的值。
有道翻译了下,翻译结果如下:
自签名SSL证书被阻塞: 通过在设置> General中关闭“SSL证书验证”来修复这个问题。 至此找到解决方法。
获取不到 postdata 其他原因
//这里的content-type要是小写
if(req.headers['content-type'] !== 'application/json'){ resolve({}) return }
cookie
存储在浏览器的一段字符串,最大5kb;
跨域不共享;
格式k1=v1;k2=v2;k3=v3; 可存储结构化数据;
每次发送http请求,会将请求域中的cookie 一起发送给sever;
server 可以修改cookie 并返回给浏览器;
浏览器可以通过js修改cookie(服务器端可限制 http-only ,仅允许服务器端修改cookie);
登录解决方案
1、cookie (弃用)
问题:暴露信息;存储量小;
2、session(弃用)
cookie中存储userid ,server 端对应 username 。
问题:session 存储在进程中,多进程之间数据不共享;操作系统会限制一个进程的最大可用内存。
3、使用redis
优势:内存数据库(mysql 是硬盘数据库),访问速度块,独立可扩展。
安装redis
brew install redis
redis使用
和前端联调
登录功能依赖cookie,需使用浏览器调试;
cookie跨域不共享,前端和server端使用 nignx 做代理达到同域目的;
nginx
高性能的web服务器,开源免费;
一般用于做静态服务、负载均衡、反向代理;
下载 nginx
brew install nginx
使用 nginx
测试配置文件是否正确 nginx -t
启动 nginx
重启 nginx -s reload
停止 nginx -s stop
配置nginx
打开配置文件
sudo vi /usr/local/etc/nginx/nginx.conf
刚启动 vim,便进入了命令模式。
按下i,切换到输入模式,以输入字符。
在输入模式中,可以使用 ESC 退出输入模式,切换到命令模式。
命令模式中使用英文 : 切换到底线命令模式,以在最底一行输入命令,:wq 储存后离开。
按ESC键可随时退出底线命令模式。
服务器用 8000,web端用 8001开启 http-server 服务,静态页面访问 8080。
注意:需要重启nginx使修改的配置生效。
重启报错:
/usr/local/var/run/nginx/nginx.pid" failed (2: No such file or directory)
解决:
nginx -c /usr/local/etc/nginx/nginx.conf
然后再 nginx -s reload 或者 nginx -s reopen
启动项目
启动nginx
不报错表示启动成功
日志
写日志
const fs = require('fs')
const path = require('path')
//写日志
function writeLog(writeStream,log){
writeStream.write(log+'\n')
}
//生成 write stream
function createWriteStream(fileName){
const fullFileName = path.join(__dirname,'../','../','logs',fileName)
const writeStream = fs.createWriteStream(fullFileName,{
flag:'a'
})
return writeStream
}
//写访问日志
const accessWriteStream = createWriteStream('access.log')
function access(log){
writeLog(accessWriteStream,log)
}
module.exports={
access
}
拆分日志
#!/bin/sh
cd /Users/mumu/Documents/code/blog-1/logs
cp access.log $(date +%y-%m-%d).access.log
echo "" > access.log
分析日志
const fs = require('fs')
const path = require('path')
const readline = require('readline')
//文件名
const fileName = path.join(__dirname,'../','../','logs','access.log')
//创建 readStream
const readStream = fs.createReadStream(fileName)
//创建 readline 对象
const rl = readline.createInterface({
input:readStream
})
let chromeNum = 0
let sum = 0
//逐行读取
rl.on('line',lineData=>{
if(!lineData){
return
}
sum ++
const arr = lineData.split('--')
if(arr[2] && arr[2].indexOf('Chrome') > 0){
chromeNum ++
}
})
//监听读取完成
rl.on('close',()=>{
console.log('chrome 占比',(chromeNum/sum*100).toFixed(2),' %')
})
项目安全
预防 sql 注入
escape:mysql.escape
const login = (username,password)=>{
username = escape(username)
password = escape(password)
const sql =`select username,realname from users where username=${username} and password=${password}`;
return exec(sql).then(rows=>{
return rows[0] || {}
})
}
预防xss攻击
密码加密
使用加密算法加密密码
const crypto = require('crypto')
//密钥
const SECRET_KEY = 'fWyuJiol_1687*76#'
//md5加密
function md5(content){
let md5 = crypto.createHash('md5')
return md5.update(content).digest('hex')
}
//加密函数
function genPassword(password){
const str = `password=${password}&key=${SECRET_KEY}`
return md5(str)
}
// const result = genPassword('123')
// console.log('加密后的密码是:',result)
module.exports = {
genPassword
}
使用框架 express
express下载
npm install express-generator -g
开始一个express项目
express express-test
npm install
npm run dev
使用框架koa2
koa下载之普通安装
npm i koa
koa下载之使用脚手架安装
默认前端视图文件(view)使用的是 pug
npm install koa-generator -g
开始一个koa2项目
koa2 koa2-test
npm install
安装环境参数
npm i cross-env --save-dev
修改入口文件 bin/www.js 中端口(默认端口3000)
var port = normalizePort(process.env.PORT || '8000');
启动项目
npm run dev