Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

提高效率的在线工具

发表于 2019-08-06

在此记录一些常用在线工具,提高工作效率。

百度文库在线下载

在某个文档页面的网址域名后面加上 vvv 三个字母,访问后就可以快捷下载。

比如:

https://wenku.baidu.com/view/3e6d30b2fd0a79563c1e72bd.html

加上 vvv 为:

https://wenku.baiduvvv.com/view/3e6d30b2fd0a79563c1e72bd.html

商品历史价格查询

在电商网站商品详情页的网址域名后面加入vvv三个字母访问后即可查询该商品的历史价格。

例如:

https://detail.tmall.com/item.htm?id=527080261251

添加vvv后变为:

https://detail.tmallvvv.com/item.htm?id=527080261251

参考链接

  1. VVV文档在线导出工具,by vvv.
  2. 商品历史价格查询,by hisprice.

Nodejs调试入门

发表于 2019-07-31 | 更新于 2024-01-21

调试是每个程序员必备的技能,因此选择合适的调试工具能极大地方便我们调试代码。Node.js 的调试方式也有很多,常见的有:

  1. 万能的 console.log
  2. debugger
  3. node –inspect + chrome devtools

本文重点介绍最有用的node –inspect方法。具体步骤如下:

  1. node –inspect app.js
  2. 打开 Chrome 浏览器,访问 chrome://inspect,选择第一步的调试目标。
  3. 在chrome访问源代码,设置断点调试。

参考链接

  1. 《Node.js 调试指南》,by nswbmw.
  2. Node.js Power Tools: 13 Libraries Every Developer Should Know,by Pinjari Rehan.

Mock数据

发表于 2019-07-28 | 更新于 2019-08-08

在实际开发中,最理想的前后端交互方式当然是后端先帮前端 mock 数据,然后前端开发,但现实很骨感,总会因为种种原因,前端需要自己来 mock 假数据。常用的伪造假数据的库有:Mockjs和easy-mock。这两个库有各自问题,因此需要一种新的 mock 假数据方案。

Mockjs

原理是: 拦截了所有的请求并代理到本地,然后进行数据模拟,所以你会发现 network 中没有发出任何的请求。

但它的最大的问题是就是它的实现机制。它会重写浏览器的XMLHttpRequest对象,从而才能拦截所有请求,代理到本地。

大部分情况下用起来还是蛮方便的,但就因为它重写了XMLHttpRequest对象,所以比如progress方法,或者一些底层依赖XMLHttpRequest的库都会和它发生不兼容。

另外,因为是它是本地模拟数据,实际上不会走任何网络请求。所以本地调试起来很蛋疼,只能通过console.log来调试。

easy-mock

天然支持跨域,还是支持MockJs的所有语法。但因为用的人多了,它的免费服务会经常的挂,可以说天天挂。官方的建议是自己搭建服务。如果你的公司整体搭建一个这样的 mock 服务的话也是一个不错的选择。但大部分人可能还是没有这个技术条件的。

新的Mock假数据方案

本地会启动一个mock-server来模拟数据,线上环境还是继续使用mockjs来进行模拟(因为本项目是一个纯前端项目,你也可以自己搭建一个线上 server 来提供数据)。不管是本地还是线上所以的数据模拟都是基于mockjs生成的,所以只要写一套 mock 数据,就可以在多环境中使用。

该方案的好处是,在保留 mockjs 的优势的同时,解决之前的痛点。由于我们的 mock 是完全基于webpack-dev-serve来实现的,所以在你启动前端服务的同时,mock-server就会自动启动,这里还通过 chokidar 来观察 mock 文件夹内容的变化。在发生变化时会清除之前注册的mock-api接口,重新动态挂载新的接口,从而支持热更新。有兴趣的可以自己看一下代码 mock-server.js。由于是一个真正的server,所以你可以通过控制台中的network,清楚的知道接口返回的数据结构。并且同时解决了之前mockjs会重写 XMLHttpRequest对象,导致很多第三方库失效的问题。

vue.config.js中配置本地mock-server服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
devServer: {
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
// change xxx-api/login => mock/login
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://127.0.0.1:${port}/mock`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
},
// 输入app为exress实例,即var app = express();
// after: function(app, server) {
// do fancy stuff
// }
after: require('./mock/mock-server.js')
}

参考链接

  1. 手摸手,带你用vue撸后台 系列五(v4.0新版本),by 花裤衩.
  2. Getting Started,by mockjs.

JavaScript最新语法学习笔记

发表于 2019-07-28 | 更新于 2023-04-04

JavaScript目前发展很快,明年都会出一些新的语法特性。为了便于学习,本文对一些遇到的JavaScript语法特性做一些笔记。

JavaScript版本简介

JavaScript 由 Brendan Eich 于 1995 年发明,并于 1997 年成为 ECMA 标准。

ECMAScript 是该语言的官方名称。

从 2015 年起,ECMAScript 按年命名(ECMAScript 2015)。

ECMAScript 版本
版本 官方名称 描述
1 ECMAScript 1 (1997) 第一版。
2 ECMAScript 2 (1998) 只改变编辑方式。
3 ECMAScript 3 (1999) 添加了正则表达式。添加了 try/catch。
4 ECMAScript 4 从未发布过。
5 ECMAScript 5 (2009) 添加了“严格模式”。添加了 JSON 支持。添加了 String.trim()。添加了 Array.isArray()。添加了数组迭代方法。
5.1 ECMAScript 5.1 (2011) 编辑改变。
6 ECMAScript 2015 添加了 let 和 const。添加了默认参数值。添加了 Array.find()。添加了 Array.findIndex()
7 ECMAScript 2016 添加了指数运算符(**)。添加了 Array.prototype.includes。
8 ECMAScript 2017 添加了字符串填充。添加了新的 Object 属性。添加了异步功能。添加了共享内存。
9 ECMAScript 2018 添加了 rest / spread 属性。添加了异步迭代。添加了 Promise.finally()。增加 RegExp。

JavaScript新语法特性

…运算符

es6中引入扩展运算符(…),它用于把一个数组转化为用逗号分隔的参数序列,它常用在不定参数个数时的函数调用,数组合并等情形。

  • 将实现了 Iterator 接口的对象转为数组
1
2
var nodeList = document.querySelectorAll('div');  
var array = [...nodeList];

解构赋值

解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。

1
2
3
4
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }

async函数

async函数是最新的javascript异步操作方式,初始定义于ES2017。async函数声明用于定义一个返回 AsyncFunction 对象的异步函数。异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的 Promise 返回其结果。但是如果你的代码使用了异步函数,它的语法和结构会更像是标准的同步函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 获取用户信息 */
async function userInfoRoute(req, res, next) {
try {
var decoded = jwt.verify(req.body.token.split(' ')[1], appConfig.secretOrPrivateKey);
var user = await models.User.findByPk(decoded.userId);
res.json({
code: 20000,
data: user
});
} catch (err) {
res.send(406, {
message: 'Account and password are incorrect.'
});
}
}

/* 获取用户信息 */
router.post('/user_info', userInfoRoute);

ES6 class

请参考ES6篇 - class 基本语法和ES6-Class如何优雅的进行“糖化”。

参考链接

  1. JavaScript 版本,by w3school.
  2. ES6 扩展运算符 三个点(…),by ten5743.
  3. 解构赋值,by MDN web docs.
  4. async 函数的含义和用法,by 阮一峰.
  5. async function,by MDN web docs.
  6. 从面向对象设计角度,全面解读——JS中的函数与对象、Object与Function、以及原型链与继承,by scott.cgi.
  7. ES6篇 - class 基本语法,by 王锦添.
  8. ES6-Class如何优雅的进行“糖化”,by 前端小魔女.

Vuejs调试入门

发表于 2019-07-28 | 更新于 2022-08-17

每个应用,不论大小,都需要理解程序是如何运行失败的。下面将探讨调试浏览器中运行的通过 Vue CLI 生成的 Vue.js 应用程序。

前提条件

  • Chrome
  • Vue CLI
  • Vue Devtools

浏览器中展示源代码

在可以从 VS Code 调试你的 Vue 组件之前,你需要更新 webpack 配置以构建 source map。做了这件事之后,我们的调试器就有机会将一个被压缩的文件中的代码对应回其源文件相应的位置。这会确保你可以在一个应用中调试,即便你的资源已经被 webpack 优化过了也没关系。

打开 config/index.js 并找到 devtool 属性。将其更新为:

如果你使用的是 Vue CLI 2,请设置并更新 config/index.js 内的 devtool 属性:

1
devtool: 'source-map',

如果你使用的是 Vue CLI 3,请设置并更新 vue.config.js 内的 devtool 属性:

1
2
3
4
5
module.exports = {
configureWebpack: {
devtool: 'source-map'
}
}

调试方法

在Chrome浏览器中调试

利用Chrome浏览器的开发工具,在Vuejs应用源代码中设置断点,进行调试。

在Chrome浏览器中调试

图1 在Chrome浏览器中调试

简单的 debugger 语句

可以直接在代码中使用原生的 debugger 语句。如果你选择了这种方式,请千万记得当你调试完毕之后把这个语句移除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
export default {
data() {
return {
message: ''
}
},
mounted() {
const hello = 'Hello World!'
debugger
this.message = hello
}
};
</script>

参考链接

  1. 在 VS Code 中调试,by vuejs.
  2. 下载并安装vue-devtools(详细步骤),by 鲤鱼砸龙门.
  3. vue调试工具vue-devtools的安装,by web前端.

ESLint工具入门教程

发表于 2019-07-27 | 更新于 2019-09-03

ESLint最初是由Nicholas C. Zakas 于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具。

ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。在许多方面,它和 JSLint、JSHint 相似,除了少数的例外:

  • ESLint 使用 Espree 解析 JavaScript。
  • ESLint 使用 AST 去分析代码中的模式
  • ESLint 是完全插件化的。每一个规则都是一个插件并且你可以在运行时添加更多的规则。

用户指南

先决条件:Node.js (>=6.14), npm version 3+。

你可以使用 npm 安装 ESLint:

1
npm install eslint --save-dev

紧接着你应该设置一个配置文件:

1
./node_modules/.bin/eslint --init

之后,你可以在任何文件或目录上运行ESLint如下:

1
./node_modules/.bin/eslint yourfile.js

也可以在全局而不是本地安装 ESLint (使用 npm install eslint –global)。但是,你使用的任何插件或可共享配置都必须安装在本地。

命令行

命令行工具有几个选项,你可以通过运行 eslint -h 查看所有选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
eslint [options] file.js [file.js] [dir]

Basic configuration:
--no-eslintrc Disable use of configuration from .eslintrc.*
-c, --config path::String Use this configuration, overriding .eslintrc.* config options if present
--env [String] Specify environments
--ext [String] Specify JavaScript file extensions - default: .js
--global [String] Define global variables
--parser String Specify the parser to be used
--parser-options Object Specify parser options
--resolve-plugins-relative-to path::String A folder where plugins should be resolved from, CWD by default

Specifying rules and plugins:
--rulesdir [path::String] Use additional rules from this directory
--plugin [String] Specify plugins
--rule Object Specify rules

Fixing problems:
--fix Automatically fix problems
--fix-dry-run Automatically fix problems without saving the changes to the file system
--fix-type Array Specify the types of fixes to apply (problem, suggestion, layout)

Ignoring files:
--ignore-path path::String Specify path of ignore file
--no-ignore Disable use of ignore files and patterns
--ignore-pattern [String] Pattern of files to ignore (in addition to those in .eslintignore)

Using stdin:
--stdin Lint code provided on <STDIN> - default: false
--stdin-filename String Specify filename to process STDIN as

Handling warnings:
--quiet Report errors only - default: false
--max-warnings Int Number of warnings to trigger nonzero exit code - default: -1

Output:
-o, --output-file path::String Specify file to write report to
-f, --format String Use a specific output format - default: stylish
--color, --no-color Force enabling/disabling of color

Inline configuration comments:
--no-inline-config Prevent comments from changing config or rules
--report-unused-disable-directives Adds reported errors for unused eslint-disable directives

Caching:
--cache Only check changed files - default: false
--cache-file path::String Path to the cache file. Deprecated: use --cache-location - default: .eslintcache
--cache-location path::String Path to the cache file or directory

Miscellaneous:
--init Run config initialization wizard - default: false
--debug Output debugging information
-h, --help Show help
-v, --version Output the version number
--print-config path::String Print the configuration for the given file

修复警告和错误

1
eslint --fix file.js [file.js] [dir]

参考链接

  1. ESLint 可组装的JavaScript和JSX检查工具,by ESLint homepage.
  2. VsCode保存时自动修复Eslint错误,by 前端进阶积累.

Vue-js入门简介

发表于 2019-07-26 | 更新于 2023-03-23

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue实例生命周期图示

Vue实例生命周期图示

核心插件Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex工作原理示意图

Vuex核心store

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutation:

1
2
3
4
5
6
7
8
9
10
11
12
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)

const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})

现在,你可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:

1
2
3
store.commit('increment')

console.log(store.state.count) // -> 1

Vuex核心概念

State

Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)):

1
2
3
4
5
6
7
8
9
10
11
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})

通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。

Getter

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

Getter 接受 state 作为其第一个参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})

Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:

1
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]

Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

1
2
3
4
5
6
7
8
9
10
11
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})

你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:

1
store.commit('increment')

注意,Mutation必须是同步函数。

Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})

Action 通过 store.dispatch 方法触发:

1
store.dispatch('increment')

Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}

const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}

const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

参考链接

  1. Vue.js 教程,by Vue.js Homepage.
  2. Vuex教程,by Vue.js Homepage.
  3. vue 页面销毁函数_45. 聊聊 Vue 的生命周期,by atone2003.
  4. 使用vue-router切换组件时使组件不销毁,by 龙易安.

Lodash入门简介

发表于 2019-07-25

Lodash是一个一致性、模块化、高性能的 JavaScript 实用工具库。

安装

浏览器环境:

1
<script src="lodash.js"></script>

通过 npm:

1
2
$ npm i -g npm
$ npm i --save lodash

Node.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Load the full build.
var _ = require('lodash');
// Load the core build.
var _ = require('lodash/core');
// Load the FP build for immutable auto-curried iteratee-first data-last methods.
var fp = require('lodash/fp');

// Load method categories.
var array = require('lodash/array');
var object = require('lodash/fp/object');

// Cherry-pick methods for smaller browserify/rollup/webpack bundles.
var at = require('lodash/at');
var curryN = require('lodash/fp/curryN');

优点

Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。

Lodash 的模块化方法 非常适用于:

  • 遍历 array、object 和 string
  • 对值进行操作和检测
  • 创建符合功能的函数

示例

1
2
3
4
_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });
// → { 'a': 1, 'b': 2 }
_.partition([1, 2, 3, 4], n => n % 2);
// → [[1, 3], [2, 4]]

参考链接

  1. Lodash,by lodash homepage.

express-jwt使用帮助

发表于 2019-07-25 | 更新于 2019-07-31

express-jwt是一个验证JsonWebTokens并设置req.user的connect/express中间件。此模块允许您使用Node.js应用程序中的JWT令牌验证HTTP请求。 JWT通常用于保护API端点,通常使用OpenID Connect发布。

Json web token结构

JWT 的三个部分依次如下:

  • Header(头部)
  • Payload(负载)
  • Signature(签名)

Header

Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

上面代码中,alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。最后,将上面的 JSON 对象使用 Base64URL 算法转成字符串。

Payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。

1
2
3
4
5
6
7
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。

1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。这个 JSON 对象也要使用 Base64URL 算法转成字符串。

Signature

ignature 部分是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

1
2
3
4
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用”点”(.)分隔,就可以返回给用户。

基于JWT的身份验证流程

使用基于 JWT 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

jsonwebtoken的使用

jsonwebtoken是JSON Web Tokens在Nodejs平台的实现。它可以与express-jwt模块配合,在expressjs中实现基于JWT的身份验证。

安装步骤

1
npm install jsonwebtoken --save

使用帮助

在expressjs中主要使用该模块生成JSON Web Tokens。其接口定义为:

  • jwt.sign(payload, secretOrPrivateKey, [options, callback])
1
2
3
4
5
6
var token = jwt.sign({
userId: users[0].id
},
appConfig.secretOrPrivateKey, {
expiresIn: 60 * 60 * 6
});
  • jwt.verify(token, secretOrPublicKey, [options, callback])
1
2
3
// verify a token symmetric - synchronous
var decoded = jwt.verify(req.body.token.split(' ')[1], appConfig.secretOrPrivateKey);
var user = await models.User.findByPk(decoded.userId);
  • jwt.decode(token [, options])
1
2
3
4
5
6
7
// get the decoded payload ignoring signature, no secretOrPrivateKey needed
var decoded = jwt.decode(token);

// get the decoded payload and header
var decoded = jwt.decode(token, {complete: true});
console.log(decoded.header);
console.log(decoded.payload)

express-jwt的使用

安装帮助

1
npm install express-jwt --save

使用示例

1
2
3
4
5
6
7
8
9
10
app.use(expressJWT({
secret: appConfig.secretOrPrivateKey
}));

app.use(function(err, req, res, next) {
console.log(err);
if (err.name === 'UnauthorizedError') {
res.status(err.status || 401).send(err.message);
}
});

参考链接

  1. 什么是 JWT – JSON WEB TOKEN, by Dearmadman
  2. JSON Web Token 入门教程,by 阮一峰.
  3. Cookie,Session和Token会话知识整理,by jack huang.
  4. node-jsonwebtoken,by auth0.

Expressjs组件morgan保存日志到文件的方法

发表于 2019-07-24 | 更新于 2019-07-25

morgan是express默认的日志中间件,也可以脱离express,作为node.js的日志组件单独使用。

示例

将日志打印到本地文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var express = require('express');
var app = express();
var morgan = require('morgan');
var fs = require('fs');
var path = require('path');

var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), {flags: 'a'});

app.use(morgan('short', {stream: accessLogStream}));
app.use(function(req, res, next){
res.send('ok');
});

app.listen(3000);

日志切割

一个线上应用,如果所有的日志都落地到同一个本地文件,时间久了,文件会变得非常大,既影响性能,又不便于查看。这时候,就需要用到日志分割了。

借助file-stream-rotator插件,可以轻松完成日志分割的工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var FileStreamRotator = require('file-stream-rotator')
var express = require('express')
var fs = require('fs')
var morgan = require('morgan')
var path = require('path')

var app = express()
var logDirectory = path.join(__dirname, 'log')

// ensure log directory exists
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory)

// create a rotating write stream
var accessLogStream = FileStreamRotator.getStream({
date_format: 'YYYYMMDD',
filename: path.join(logDirectory, 'access-%DATE%.log'),
frequency: 'daily',
verbose: false
})

// setup the logger
app.use(morgan('combined', {stream: accessLogStream}))

app.get('/', function (req, res) {
res.send('hello, world!')
})

参考链接

  1. Node 进阶:express 默认日志组件 morgan 从入门使用到源码剖析,by 程序猿小卡.
上一页1…363738…53下一页

Jack Huang

521 日志
67 标签
© 2025 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse