Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

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 程序猿小卡.

Expressjs cors入门简介

发表于 2019-07-24

在nodejs+expressjs+vuejs的解决方案中,服务器端应用开发和前端应用的开发是独立的。不过前端应用调用服务器端应用的RESTful API时涉及跨域资源访问,因此需要添加expressjs的cors模块。下面简要介绍cors模块的使用方法。

跨域资源共享简介

跨域资源共享(CORS)是一种机制,允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。网页可以自由嵌入跨源图像,样式表,脚本,iframe和视频。但某些“跨域”请求,尤其是Ajax请求,默认情况下是由同源安全策略禁止的。

CORS定义了一种浏览器和服务器可以交互的方式,以确定允许跨源请求是否安全。它允许比纯粹的同源请求更多的自由和功能,但比简单地允许所有跨源请求更安全。 CORS规范最初是作为W3C建议书发布的,但该文件已经过时。目前主动维护的CORS定义规范是WHATWG的Fetch Living Standard。

CORS标准描述了新的HTTP标头,它为浏览器提供了一种仅在获得许可时才能请求远程URL的方法。 尽管服务器可以执行某些验证和授权,但浏览器通常负责支持这些标头并遵守它们所施加的限制。

对于可以修改数据的Ajax和HTTP请求方法(通常是GET以外的HTTP方法,或者某些MIME类型的POST用法),规范要求浏览器“预检”请求,通过HTTP OPTIONS请求从服务器请求支持的方法 方法,然后,在服务器“批准”时,使用实际的HTTP请求方法发送实际请求。 服务器还可以通知客户端是否应该随请求一起发送“凭证”(包括Cookie和HTTP身份验证数据)。

跨域资源共享流程图

图1 跨域资源共享流程图

CORS安装

CORS是一个node.js包,用于提供Connect / Express中间件,可用于启用具有各种选项的CORS。使用如下方式安装。

1
npm install cors --save

CORS示例

  • 简单示例,允许所有跨域请求
1
2
3
4
5
6
7
8
9
10
11
12
13
var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})

参考链接

  1. Cross-origin resource sharing,by wikipedia.
  2. 跨域资源共享 CORS 详解,by 阮一峰.
  3. cors,by expressjs.com.

nodemon入门简介

发表于 2019-07-23

Nodemon是一个用于nodejs开发的工具程序,它将监视nodejs源中的任何更改并自动重新启动服务器。

nodemon不需要对代码或开发方法进行任何其他更改。 nodemon是node的替换包装器,在执行脚本时使用nodemon替换命令行上的单词node即可。

安装

1
npm install -g nodemon

使用

1
nodemon [your node app]

参考链接

  1. nodemon,by remy.
  2. 在 Express 开发中使用 nodemon,by bubkoo.

RESTful_API设计及测试入门

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

RESTful API是目前比较成熟的一套互联网应用程序的API设计理论,提供了一种统一的机制,方便不同的前端设备与后端进行通信,以应对前端设备层出不穷(手机、平板、桌面电脑、其他专用设备……)的状况。同时对开发人员而言,提供了一种规范,方便协作开发,降低了API接口设计的难度。

RESTful API设计规范

请参考阮一峰老师的RESTful API 设计指南。

RESTful API的测试方法

RESTful API设计好了之后,需要测试其可用性。常用的API测试工具有Postman。简单入门可参考Postman 安装及使用入门教程。

Postman中使用HTTP POST方法测试RESTful API时,需要了解POST提交数据的方法。

POST提交数据的方法

POST 几种请求主要包括 application/x-www-form-urlencoded、 multipart/form-data、 application/json、text/xml 四种的方法。

服务端通常是根据请求头(Request Headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。
POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。

  • application/x-www-form-urlencoded (默认常用)

这是最常见的 POST 提交数据的方式。浏览器的原生表单,如果不设置Content-type属性,就会默认该方式提交数据,并且提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。

  • multipart/form-data

这是另一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让表单的enctyped等于 multipart/form-data。

  • application/json

application/json 这种方案,可以方便的提交复杂的结构化数据,这种POST提交方式越来越多,用来告诉服务端消息主体是序列化后的 JSON 字符串。

由于JSON规范的流行,出了低版本的IE之外,各大浏览器都支持 JSON.stringify 将JSON数据字符串化(编码)传到服务器,还可以通过 JSON.parse 将字符串转化(解码)为JSON数据供前端渲染或者其他处理。

  • text/xml

现在基本不用。

参考链接

  1. RESTful API 设计指南,by 阮一峰.
  2. RESTful API 设计最佳实践,by Philipp Hauer.
  3. restful-api-design-references,by aisuhua.
  4. Postman Doc,by postman homepage.
  5. Postman 安装及使用入门教程,by Mafly.
  6. 四种常见的 POST 提交数据方式,by Jerry Qu.
上一页1…373839…53下一页

Jack Huang

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