推荐几个有助于学习的网站
console
$0、$1...点击选择标签顺序
-
console.table();
数据表格化
-
console.time();
console.time("abcd"); var arr = []; for(var i = 0;i < 10000; i++){ arr.push(i); } console.timeEnd("abcd");查看代码执行效率
-
monitorEvents();
查看事件执行顺序
-
console.error();
打印错误提示
Typora(编辑markdown)
#一级标题
## 二级标题
-无序列表
````js编辑js代码前后一个包裹代码
*斜体
**加粗
图片直接拖
>前言
---分割线
EJS(模板渲染引擎)
入门
安装ejs
npm install ejs
express设置渲染引擎为ejs
app.set('view engine','ejs')
将模板字符串和一些数据作为参数传递给EJS,Duang,HTML出来了。
var ejs = require('ejs'),
people = ['geddy','neil','alex'],
html = ejs.render('<%= people.join(","); %>',{
people:people
});
文档
实例
<% if(user) { %>
<h2><%= user.name %></h2>
<% } %>
用法
var template = ejs.compile(str, options);
template(data);
// => 输出绘制后的 HTML 字符串
esj.render(str,data,options);
// => 输出绘制后的 HTML 字符串
ejs.renderFile(filename,data,options,function(err,str){
// str => 输出绘制后的 HTML 字符串
});
参数
cache缓存编译后的函数,需要提供filenamefilename被cache参数用做键值,同时也用于include语句context函数执行时的上下文环境compileDebug当为false时不编译调试语句client返回独立的编译后的函数delimiter`放在角括号中的字符,用于标记标签的开与闭
debug将生成的函数体输出_with是否使用with() {}结构。如果为false,所有局部数据将储存在locals对象上。localsName如果不使用with,localsName将作为储存局部变量的对象的名称。默认名称是localsrmWhitespace删除所有可安全删除的空白字符,包括开始与结尾处的空格。对于所有标签来说,它提供了一个更安全版本的-%>(在一行的中间并不会剔除标签后面的换行符)。escape为<%=结构设置对应的转义(escape)函数。它被用于输出结果以及在生成的客户端函数中通过toString()输出。(默认转义XML)。
标签含义
-
<%'脚本'标签,用于流程控制,无输出。 -
<%_删除其前面的空格符 -
<%=输出数据到模板(输出是转义HTML标签) -
<%-输出非转义的数据到模板 -
<%#注释标签,不执行,不输出内容 -
<%%输出字符串‘<%’ -
%>一般结束标签 -
-%>删除紧跟其后的换行符 -
_%>将结束标签后面的空格符删除
包含(include)
通过include指令将相对于模板路径中的模板片段包含进来。(需要提供‘filename’参数。)例如,如果存在“./views/users.ejs”和“./views/user/show.ejs”两个模板文件,你可通过<%- include('user/show'); %>代码包含后者。
你可能需要能够输出原始内容的标签(<%-)用于include指令,避免对输出的HTML代码做转义处理。
<ul>
<% users.forEach(function(user){ %>
<%- include('user/show',{user: user}); %>
<% }); %>
})
</ul>
自定义分隔符
可针对单个模板或全局使用自定义分隔符:
var ejs = require('ejs'),
users = ['geddy','neil','alex'];
//单个模板文件
ejs.render('<?= users.join(" | "); ?>',{
users:users
},{
delimiter:'?'
});
// => 'geddy | neil | alex'
//全局
ejs.delimiter = '$';
ejs.render('<$= users.join(" | "); $>',{
users:users
});
// => 'geddy | neil | alex'
cmd几个小命令
ls: 查看当前目录下有哪些文件(夹),可以加上-a参数显示所有文件(夹)
ll: 同ls, 只是显示方式不一样
clear: 清屏
pwd: print work directory, 打印工作目录的路径
cd 目录: 进入某个目录, 如果不跟用户名,直接进行用户的根目录
mkdir 目录名:创建一个目录
touch 文件名:创建一个文件
rm -rf 文件或者目录名: 删除一个文件或者一个目录
node.js
npm init: 初始一个项目, 加-y参数可以不用提示直接创建package.json
在package.json 里可以添加任意的执行脚本。
如果node项目要监听代码的修改,可以使用nodemon
// http是node原生模块,不需要安装可以直接引入
const http = require('http')
// 使用http.createServer的方法创建一个server
const app = http.createServer((req, res) => {
res.end('hello 1901!')
})
// 让server运行起来吧!!!
app.listen(3000, () => {
console.log('server is running on http://localhost:3000')
})
一般在项目中,不会使用原生的方式来写应用。推荐有一些nodejs的框架
- express
- koa
express
首先要安装npm i express -S
创建一个基本的express应用
// 从express包里引入express方法, 这个不是原生的模块,所以需要先安装`npm i express -S`
const express = require('express')
// 创建一个express实例
const app = express()
// 定义一个路由,这个路由是通过get方法访问,当访问的时候,服务器发送一个响应给客户端
app.get('/', (req, res) => {
res.send('hello express')
})
// 要让app运行起来,需要监听
app.listen(3000, () => {
console.log('server is running on http://localhost:3000')
})
就可以通过http://localhost:3000访问,你将看到页面上有 hello express
express-generator
npm list -g --depth=0 查看全局安装
npx临时使用包
npx express-generator backend 临时安装express-generator 包到backend文件夹中
app.js
//创建HTTP状态错误信息
var createError = require('http-errors');
//express
var express = require('express');
//原生模块path
var path = require('path');
//express的cookie处理中间件(middleware)
var cookieParser = require('cookie-parser');
//日志中间件
var logger = require('morgan');
//引入首页的路由
var indexRouter = require('./routes/index');
//引入users的路由
var usersRouter = require('./routes/users');
//引入asce的路由
var asceRouter = require('./routes/asce');
//创建express的实例
var app = express();
// view engine setup 设置view渲染引擎为ejs
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//app.use是实例上的方法,表示应用中间件
app.use(logger('dev'));
//这里两句就是来处理请求参数
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// 把路由也当成中间件来挂载
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/', asceRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
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 : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
//相当于返回
module.exports = app;
用来处理请求参数(现在用的)
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
以前用的
var bodyParser = require('body-parser')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
有这两句就可以在路由里面取到req.body
bcrypt
在用户模块,对于用户密码的保护,通常都会进行加密。我们通常对密码进行加密,然后存放在数据库中,在用户进行登录的时候,将其输入的密码进行加密然后与数据库中存放的密文进行比较,以验证用户密码是否正确。了解全部
安装
npm install bcrypt
const bcrypt = require('bcrypt');//引入模块
const saltRounds = 10;//系统自定义密码的长度
const myPlaintextPassword = 's0/\/\P4$$w0rD';//我的明文密码
const someOtherPlaintextPassword = 'not_bacon';//其他明文密码
加密
bcrypt.genSalt(saltRounds, function(err, salt) {
//salt 是bcrypt加的字符串
bcrypt.hash(password, salt, function(err, password) {
//前password是请求的密码 后password 是请求的密码和salt组合的加密字符串
}
}
密码对比
//如果用户存在就进行密码比对,使用bcrypt的compare的方法
//第一个参数为请求的密码,第二个为数据库中的密码
//find出来的是数组
bcrypt.compare(password, resp[0].password, function(err, result) {
}
MongoDB
安装MongoDB
新建文件夹
c:\data\db
命令行下运行MongoDB服务器
必须从MongoDB目录中的bin目录执行mongod.exe
c:\mongodb\bin\mongod --dbpath c:\data\db
连接MongoDB
c:\mongodb\bin\mongo
查看数据库
show dbs
$ npm i mongoose安装mongoose包 app连接mongodb
fetch请求
做原生ajax请求的方式 了解全部
fetch('/api/signup', {
body: JSON.stringify(data), //请求的数据
headers: {
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
})
.then(response => response.json())//fetch的响应不是直接的JSON,需要先调一下.json()方法,在下一个then里找到JSON
.then(resp => {
alert(resp.data.errMsg);
})
express-session
session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 session 保存在服务器上。
安装express-session模块
$ npm install express-session
session设置cookie
var session = require('express-session')//引入模块
app.use(session({
secret: 'asce nice',//加盐
cookie:{},//cookie的相关操作
name:'asce'//键名
}))
FormData
用于Ajax上传文件 了解全部
//首先需要先new一个实例
const data = new FormData();
//使用append方法添加字段 formDataInstance.append(key, value)
data.append('avatar', avatar);
//这里添加要上传的文件,注意这里的key就是后端所需要的参数名
//这里添加除了文件之外的其他字段
data.append('name','asce');
//使用ajax上传,这里使用了fatch,也可以使用jQuer,也可以使用其他任何的ajax库,比如后期咱们工作天天用的axios
fetch(url,{
method:'post',
body:data
})
.then(resp => resp.json())
.then(json =>{
//json是从后跳获取的json对象
})
后台接收前端传过来的文件
router.post('/upload',(req,res,next) => {
//因为express本身不能接收formdata,所以需要一个额外的包来处理,再express(nodejs)里,我们经常使用multer或者formidable来处理文件上传
//先实例化一个formidable.IncomingForm
const form = new formidable.IncomingForm();
//设置上传的目录,这里咱们设置到express的静态资源目录
form.uploadDir = path.join(process.cwd(),'public/uploads')
//保留扩展名
form.keepExtensions = true;
//解析请求
form.parse(req,function(err,fields,files){
//err,错误信息
//fields,除了文件以外的其他字段
//files,文件
//实际后端在工作的时候,还会去判断fields里是否有一些关于权限的字段,比如token,如果不合法,后端会把这个上传的文件删除 ,也有可能是先检测是否有权限。然后再次决定是否要返回给前端。
})
})
基于express和mock.js搭建自己的前后端分离Mock服务器
运行
$ npx express-generator api-server创建一个express项目$ cd api-server进入项目目录$ npm install安装项目所需要的依赖$ npm install nodemon -D安装nodemon$ npm install mockjs -S安装mockjs包-
打开项目目录下的
package.json, 更改scripts:- "start": "node ./bin/www" + "start": "nodemon ./bin/www" 根据需要配置路由
-
比如,有一个叫users的路由挂载在
/api/v1/users下,就可以这么来写这个mock数据// 引入express const express = require('express'); // 只使用router const router = express.Router(); // 引入Mock对象 const Mock = require('mockjs') // 定义生成数据列表的方法 const generateData = () => { // 使用Mock.mock方法来生成mock数据 return Mock.mock({ "code": 200, "data|12": [ { "id": "@id", "title": "@ctitle(15, 25)", "author": "@cname", "volume": "@int(100, 300)", "createAt": "@int(10000000000000, 1554363040517)" } ] }) } // 定义另外一个方法,用于生成单个数据 const generateDataById = (id) => { return Mock.mock({ "code": 200, data: { id, "title": "@ctitle(15, 25)", "author": "@cname", "volume": "@int(100, 300)", "createAt": "@int(10000000000000, 1554363040517)" } }) } /* 获取用户列表 */ router.get('/', function(req, res, next) { res.json(generateData()) }); /* 获取单个用户,根据用户的id, 这里有一个express通配符路由(动态路由) */ router.get('/:id', function(req, res, next) { const { id } = req.params res.json(generateDataById(id)) }); module.exports = router;这样我们就可以使用
http://localhost:port/users获取用户列表, 使用http://localhost:port/users/任意的id参数获取用户信息
简单的聊天室
安装express
$ npm install --save express
$ npm install --save socket.io
index.js
// express
const express = require('express')
// 创建实例
const app = express()
// 创建一个server
const server = require('http').createServer(app)
// 创建io对象
const io = require('socket.io')(server)
// 使用静态目录
app.use('/static', express.static(__dirname+'/public'))
// 全局只有一个路由,因为只有一个页面
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
// 当io连接的时候,有一个回调,参数是socket
io.on('connection', (socket) => {
// 每一次的连接都有一个socket.id
console.log(socket.id)
// 当客户端有收到login的事件的时候
socket.on('login', (msg) => {
// 发布一个事件到客户端
io.emit('userlogin', msg + '进入了房间')
})
socket.on('sendMsg', (msg) => {
io.emit('receiveMsg', msg)
})
})
server.listen(3000, () => {
console.log(chalk.hex('#F0F').bold('server is running on http://localhost:3000'))
})
index.html
<div class="app">
<ul class="msg-window">
</ul>
<div class="msg-form">
name:<input type="text" onchange="changeName(this)" />
message:<input type="text" id="msgInput"/>
<button onclick="sendMsg()">发送</button>
</div>
</div>
<!-- 要使用socket.io, 有一个服务端的,有一个客户端的 -->
<script src="/static/socket.io.js"></script>
<script>
// 设置一个默认的用户名
let username = '我是一颗小虎牙'
const msgWindow = document.querySelector('.msg-window')
// 初始化socket
const socket = io()
// 当初始化后,告诉一下服务器
socket.emit('login', '我是一颗小虎牙')
// 接收服务器userlogin发过来的消息
socket.on('userlogin', (msg) => {
const li = document.createElement('li')
li.innerHTML = msg
msgWindow.appendChild(li)
})
// 接收服务器receiveMsg发过来的消息
socket.on('receiveMsg', (msg) => {
const li = document.createElement('li')
li.innerHTML = `<span class="name">${msg.name}说:</span><span>${msg.data}</span>`
msgWindow.appendChild(li)
})
const changeName = (e) => {
username = e.value
}
const sendMsg = () => {
const data = msgInput.value
socket.emit('sendMsg', {
name: username,
data
})
}
</script>
同一个局域网就能进行实施聊天了