master
expressgy 2 years ago
commit 1676aef8f2
  1. 25
      .gitignore
  2. 6
      .obsidian/app.json
  3. 3
      .obsidian/appearance.json
  4. 29
      .obsidian/core-plugins-migration.json
  5. 20
      .obsidian/core-plugins.json
  6. 1
      .obsidian/hotkeys.json
  7. 261
      .obsidian/workspace.json
  8. 11
      readme.md
  9. 13
      xi-note-computer/.obsidian/app.json
  10. 8
      xi-note-computer/.obsidian/appearance.json
  11. 29
      xi-note-computer/.obsidian/core-plugins-migration.json
  12. 22
      xi-note-computer/.obsidian/core-plugins.json
  13. 1
      xi-note-computer/.obsidian/hotkeys.json
  14. 212
      xi-note-computer/.obsidian/workspace.json
  15. 0
      xi-note-computer/.trash/Golang.md
  16. 0
      xi-note-computer/.trash/JS后端框架.DIRNAME.md
  17. 1
      xi-note-computer/.trash/未命名.canvas
  18. BIN
      xi-note-computer/Static/Docker Engine.png
  19. 2
      xi-note-computer/Static/Docker.svg
  20. BIN
      xi-note-computer/Static/Docker和VMware区别.png
  21. BIN
      xi-note-computer/Static/Docker平台组成.png
  22. BIN
      xi-note-computer/Static/Docker核心.png
  23. BIN
      xi-note-computer/Static/Docker生命周期.png
  24. BIN
      xi-note-computer/Static/镜像分层原理.png
  25. 0
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/ES/ES.dirname
  26. 284
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/ES/JS 面向对象再学习.md
  27. 190
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/ES/JS高级.md
  28. 285
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/Framework/Fastify/Started入门.md
  29. 0
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/Framework/JS后端框架.DIRNAME
  30. 150
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/Framework/NestJS/NestJS.md
  31. 1493
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/JavaScript高级程序设计(第四版)深入学习.md
  32. 9
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/0001express创建.js
  33. 21
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/01.js
  34. 19
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/02.js
  35. 20
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/03.js
  36. 26
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/04.js
  37. 28
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/05.js
  38. 24
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/06.js
  39. 10
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/07.js
  40. 9
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/08.js
  41. 19
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/09.js
  42. 20
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/10.js
  43. 11
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/11.js
  44. 14
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/12.js
  45. 22
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/13.js
  46. 31
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/14.js
  47. 113
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/pc.html
  48. 14
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/post.html
  49. 15
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/router.js
  50. 10
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/static/1.html
  51. 1
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/static/a.js
  52. 0
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/static/a.mp4
  53. 1
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code/templates/index.art
  54. 19
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/code2/01cookie.js
  55. 289
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/express.md
  56. 621
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/package-lock.json
  57. 85
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/session是什么.md
  58. 77
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/express/文件说明.md
  59. 63
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/app.js
  60. 40
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/app.js
  61. 90
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/bin/www
  62. 7178
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/package-lock.json
  63. 27
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/package.json
  64. 8
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/public/stylesheets/style.css
  65. 15
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/routes/index.js
  66. 13
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/routes/users.js
  67. 6
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/views/error.jade
  68. 5
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/views/index.jade
  69. 7
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/demo/views/layout.jade
  70. 78
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/ostest.js
  71. 3936
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/package-lock.json
  72. 22
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/package.json
  73. 80
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/readme.md
  74. 8
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/routers/main/get.js
  75. 11
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/routers/routers.js
  76. 52
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/static/css/default.css
  77. 13
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/templates/input.html
  78. 10
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/templates/user.html
  79. 13
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/koa/test.js
  80. 12
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/learn-http/package.json
  81. 9
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/learn-http/server.js
  82. 0
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/learn-http/web.js
  83. 296
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/nodejs20210812.md
  84. 18
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/webDownload/express+MongoDB+file.stream+download.js
  85. 14
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/webDownload/express+download.js
  86. 855
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/webDownload/package-lock.json
  87. 5
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/Node/webDownload/package.json
  88. 448
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/尚学堂.md
  89. BIN
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/截屏2021-08-22 上午3.17.45.png
  90. 9
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/测试/S个人探索/0.0.01for循环是同步进行吗.js
  91. 13
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/测试/S个人探索/0.0.02这是轮询吗.js
  92. 11
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/测试/S个人探索/0.0.03递归.js
  93. 19
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/JS/测试/闭包/0.0.01闭包.js
  94. 714
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/TypeScript.md
  95. 6
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/001.js
  96. 12
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/001.ts
  97. 11
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/002.js
  98. 15
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/002.ts
  99. 17
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/003.js
  100. 21
      xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/003.ts
  101. Some files were not shown because too many files have changed in this diff Show More

25
.gitignore vendored

@ -0,0 +1,25 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist.*
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,6 @@
{
"showLineNumber": true,
"strictLineBreaks": true,
"livePreview": false,
"readableLineLength": false
}

@ -0,0 +1,3 @@
{
"accentColor": ""
}

@ -0,0 +1,29 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"starred": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": false
}

@ -0,0 +1,20 @@
[
"file-explorer",
"global-search",
"switcher",
"graph",
"backlink",
"canvas",
"outgoing-link",
"tag-pane",
"page-preview",
"daily-notes",
"templates",
"note-composer",
"command-palette",
"editor-status",
"starred",
"outline",
"word-count",
"file-recovery"
]

@ -0,0 +1,261 @@
{
"main": {
"id": "2218a07615f59148",
"type": "split",
"children": [
{
"id": "9149a57b66e2b18f",
"type": "tabs",
"children": [
{
"id": "9955fbf4bf564a5f",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-S-XinQu/XQ01-需求导入.md",
"mode": "source",
"source": false
}
}
},
{
"id": "77c1c070d5cc0391",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-S-XinQu/XQ02-前置功能模块.md",
"mode": "source",
"source": true
}
}
},
{
"id": "0d80a88c671858ec",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-C-操作系统/Linux/Docker/Docker.md",
"mode": "preview",
"source": true
}
}
},
{
"id": "adef42b9e025b76f",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-S-XinQu/XQ04-场景分析.md",
"mode": "source",
"source": true
}
}
},
{
"id": "2a9801334c755e55",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-S-XinQu/XQ05-数据库建设.md",
"mode": "source",
"source": true
}
}
},
{
"id": "5f4f4377096139bb",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-S-XinQu/XQ06-接口建设和自动化测试.md",
"mode": "source",
"source": true
}
}
},
{
"id": "865a0430bf7de6b4",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-S-XinQu/XQ07-建设工程控制-流程和工期.md",
"mode": "source",
"source": true
}
}
},
{
"id": "a68eb5f97f7d52fb",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "xi-note-computer/Xi-S-XinQu/XQ04-场景分析.md",
"mode": "source",
"source": true
}
}
}
],
"currentTab": 2
}
],
"direction": "vertical"
},
"left": {
"id": "031afcfa2e5c3d38",
"type": "split",
"children": [
{
"id": "9df5292d246cabad",
"type": "tabs",
"children": [
{
"id": "eeb8ccc1c5b3586e",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical"
}
}
},
{
"id": "0f4aeb5a182cb867",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
}
}
},
{
"id": "d2aa27dce7bce4b4",
"type": "leaf",
"state": {
"type": "starred",
"state": {}
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "b15348c4f378485a",
"type": "split",
"children": [
{
"id": "05912433d3ad08ad",
"type": "tabs",
"children": [
{
"id": "aa72d73ebf8c1754",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "xi-note-computer/Xi-C-操作系统/Linux/Docker/Docker.md",
"collapseAll": true,
"extraContext": true,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "2bb87078a7b9039b",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "xi-note-computer/Xi-C-操作系统/Linux/Docker/Docker.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "0eac151b5b1041f2",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "alphabetical",
"useHierarchy": true
}
}
},
{
"id": "b4869147578dd521",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "xi-note-computer/Xi-C-操作系统/Linux/Docker/Docker.md"
}
}
}
],
"currentTab": 3
}
],
"direction": "horizontal",
"width": 300
},
"left-ribbon": {
"hiddenItems": {
"canvas:新建白板": false,
"switcher:打开快速切换": false,
"graph:查看关系图谱": false,
"daily-notes:打开/创建今天的日记": false,
"templates:插入模板": false,
"command-palette:打开命令面板": false
}
},
"active": "0d80a88c671858ec",
"lastOpenFiles": [
"xi-note-computer/Xi-S-XinQu/XQ10-程序结构/微服务架构拓扑.canvas",
"xi-note-computer/Xi-S-XinQu/XQ03-需求模块分析.md",
"xi-note-computer/Xi-S-XinQu/XQ02-前置功能模块.md",
"xi-note-computer/Xi-S-XinQu/XQ01-需求导入.md",
"xi-note-computer/Xi-S-XinQu/数据库/sql.sql",
"xi-note-computer/Xi-S-XinQu/数据库",
"xi-note-computer/Xi-S-XinQu/XQ10-程序结构/用户系统数据架构.canvas",
"xi-note-computer/Xi-S-XinQu/XQ08-预期和阶段成果.md",
"xi-note-computer/Xi-S-XinQu/XQ07-建设工程控制-流程和工期.md",
"xi-note-computer/Xi-S-XinQu/XQ06-接口建设和自动化测试.md",
"xi-note-computer/Xi-S-XinQu/XQ05-数据库建设.md",
"xi-note-computer/Xi-S-XinQu/XQ04-场景分析.md",
"xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/TypeScript.md",
"xi-note-computer/Xi-S-XinQu/XQ10-程序结构",
"xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/Framework/Fastify/Started入门.md",
"xi-note-computer/Xi-S-XinQu/Readme.md",
"xi-note-computer/Xi-S-XinQu",
"xi-note-computer/Xi-C-操作系统/Windows/wsl2总结.md",
"xi-note-computer/Xi-C-操作系统/Windows",
"xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/005.ts",
"xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/TypeScript/src/005.js",
"xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/Framework/JS后端框架.DIRNAME",
"xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/Framework/Fastify",
"xi-note-computer/Xi-A-Program/Xi-A1-JavaScript/Framework"
]
}

@ -0,0 +1,11 @@
# BPEMR
> 此文件为我的档案和笔记目录,记录学习过程
touch README.md
git init
git checkout -b main
git add README.md
git commit -m "first commit"
git remote add origin http://togy.top/expressgy/BPEMR.git
git push -u origin main

@ -0,0 +1,13 @@
{
"livePreview": false,
"defaultViewMode": "preview",
"strictLineBreaks": true,
"showLineNumber": true,
"trashOption": "local",
"newFileLocation": "folder",
"newFileFolderPath": "Live",
"attachmentFolderPath": "Static",
"showUnsupportedFiles": true,
"rightToLeft": false,
"readableLineLength": true
}

@ -0,0 +1,8 @@
{
"accentColor": "",
"theme": "obsidian",
"translucency": true,
"baseFontSize": 14,
"showViewHeader": true,
"nativeMenus": false
}

@ -0,0 +1,29 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"starred": true,
"markdown-importer": true,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": true,
"file-recovery": true,
"publish": false,
"sync": false
}

@ -0,0 +1,22 @@
[
"file-explorer",
"global-search",
"switcher",
"graph",
"backlink",
"canvas",
"outgoing-link",
"tag-pane",
"page-preview",
"daily-notes",
"templates",
"note-composer",
"command-palette",
"editor-status",
"starred",
"markdown-importer",
"outline",
"word-count",
"workspaces",
"file-recovery"
]

@ -0,0 +1,212 @@
{
"main": {
"id": "2f176d200d18214b",
"type": "split",
"children": [
{
"id": "d70a335a2d9b3e28",
"type": "tabs",
"children": [
{
"id": "b39cb5dc2f076386",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Xi-S-XinQu/Readme.md",
"mode": "source",
"source": true
}
}
},
{
"id": "f45cc3df07a2e929",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Xi-S-XinQu/XQ01-需求导入.md",
"mode": "source",
"source": true
}
}
},
{
"id": "cd7fdae3e80a91d4",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "Xi-A-Program/Xi-A9-Databases/MongoDB/MongoDB官网版.md",
"mode": "source",
"source": true
}
}
}
],
"currentTab": 2
}
],
"direction": "vertical"
},
"left": {
"id": "4a37ba04e69118b6",
"type": "split",
"children": [
{
"id": "114dfc492c2d3584",
"type": "tabs",
"children": [
{
"id": "dc5d3e39d8240cca",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical"
}
}
},
{
"id": "27fe86675b840c4a",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": true,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
}
}
},
{
"id": "959fd55e91122234",
"type": "leaf",
"state": {
"type": "starred",
"state": {}
}
}
]
}
],
"direction": "horizontal",
"width": 288.5
},
"right": {
"id": "8c260bb0d243a858",
"type": "split",
"children": [
{
"id": "1acbaf85a33d2577",
"type": "tabs",
"children": [
{
"id": "d799646b979d9da0",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "Xi-A-Program/Xi-A9-Databases/MongoDB/MongoDB官网版.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "69640ca19ee2077e",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "Xi-A-Program/Xi-A9-Databases/MongoDB/MongoDB官网版.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
}
}
},
{
"id": "a52ae6ce4d5f55fb",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": false
}
}
},
{
"id": "fa99c4b5654469e2",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "Xi-A-Program/Xi-A9-Databases/MongoDB/MongoDB官网版.md"
}
}
}
],
"currentTab": 3
}
],
"direction": "horizontal",
"width": 283.5
},
"left-ribbon": {
"hiddenItems": {
"canvas:新建白板": false,
"markdown-importer:打开 Markdown 格式转换器": false,
"workspaces:管理工作区布局": false,
"switcher:打开快速切换": false,
"graph:查看关系图谱": false,
"daily-notes:打开/创建今天的日记": false,
"templates:插入模板": false,
"command-palette:打开命令面板": false
}
},
"active": "cd7fdae3e80a91d4",
"lastOpenFiles": [
"Xi-S-XinQu/XQ01-需求导入.md",
"Xi-A-Program/Xi-A9-Databases/MongoDB/MongoDB官网版.md",
"Xi-A-Program/Xi-A9-Databases/MongoDB",
"Xi-A-Program/Xi-A9-Databases",
"Xi-S-XinQu/Readme.md",
"Xi-S-XinQu/未命名",
"Xi-S-XinQu",
"未命名.canvas",
"Xi-A-Program/Xi-A1-JavaScript/Framework/Fastify/Started入门.md",
"Xi-Plan9/2023年.md",
"Xi-A-Program/Xi-A1-JavaScript/JS/JavaScript高级程序设计(第四版)深入学习.md",
"Xi-A-Program/Xi-A1-JavaScript/Framework/JS后端框架.DIRNAME",
"Xi-A-Program/Xi-A1-JavaScript/Framework/新建 文本文档.txt",
"Xi-A-Program/Xi-A1-JavaScript/Framework/JS后端框架.DIRNAME.md",
"Xi-A-Program/Xi-A1-JavaScript/Framework/Nest",
"Xi-A-Program/Xi-A1-JavaScript/Framework/Fastify",
"Xi-A-Program/Xi-A1-JavaScript/Framework",
"Xi-A-Program/Xi-A1-JavaScript/JS/尚学堂.md",
"Xi-A-Program/Xi-A1-JavaScript/JS/截屏2021-08-22 上午3.17.45.png",
"Xi-A-Program/Xi-A1-JavaScript/ES/JS 面向对象再学习.md",
"Xi-A-Program/Xi-A1-JavaScript/ES/JS高级.md",
"Xi-A-Program/Xi-A1-JavaScript/TypeScript/TypeScript.md",
"Xi-C-操作系统/Windows/wsl2总结.md",
"Xi-C-操作系统/Windows",
"Xi-A-编程/Xi-A1-JavaScript语言/JS/尚学堂.md",
"Xi-A-编程/Xi-A2-前端知识/HTML/尚学堂.md",
"Xi-A-编程/Xi-A3-GoLang/Golang.md",
"Xi-C-操作系统/Linux/Docker/Docker.md",
"Xi-C-操作系统/Linux/ArchLinux.svg",
"Xi-C-操作系统/Linux/UFW.md",
"Xi-C-操作系统/Linux/Shell.md",
"Xi-C-操作系统/Linux/Docker/Docker.svg",
"Xi-C-操作系统/Linux/Docker/docker.png"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

@ -0,0 +1,284 @@
# JS 面向对象再学习
```js
class Satr{
constructor(name){
this.name = name;
}
}
```
```js
class Father{
constructor(xing){
this.xing = xing;
}
say(){
return 'i am father'
}
}
class Son extends Father{
construvtor(xing, ming){
super(xing);// super必须在子类this之前调用
this.ming = ming
console.log(this.xing, this.ming)
}
say(){
console.log(super.say() + '的儿子')
}
}
```
类再ES6没有变量提升,不能再类定义之前使用类
利用构造函数创建对象
```js
function Star(name, age){
this.name = name;
this.age = age;
this.song = function() {
console.log(' ican sing song.')
}
}
Star.sex = "男";// 静态成员,只能通过构造函数访问,Satr
const 张学友 = new Start('张学友', 18)
```
*this创建的对象为实例对象,实例对象只能用实例化的对象调用,也就是需要被 <u>new</u>*
构造函数创建实例都西昂浪费空间,对象内复杂的对象在实例化的时候会开辟新的内存
```js
function A(){
this.run = function(){
return 'Hello World!'
}
}
const b = new A();
const c = new A();
b.run === c.run;// false
```
**每一个构造函数都有一个原型对象 <u>prototype</u> **
每一个实例共享对象
实例对象的`__proto__`指向原型对象的`prototype`
先查找对象身上的,案子查看`__proto__`上的
`__proto__`和`prototype`中的`constructor`指向构造函数本身(这也是他的作用)
构造函数的`prototype`被覆盖了的话用`constructor`指回原来的构造函数
call调用函数,并改变this
```js
function fn(){
console.log('Hello,world!');
}
fn.call();// Hello,world!
// fn的this为window
fn.call(obj);
// fn的this为obj
function a(x, y){
console.log(this, x, y)
}
a.call(obj, x, y);// 第一个参数是this指向
```
```js
function Father(name){
this.name = name;
}
function Son(name){
Father.call(this, name);// call执行了Father,并把自己的this传递进去,此时,Father进行this.name = name操作实际上是给Son添加name
}
Son.prototype = Father.prototype;
Son.prototype.constructor = Son;
// 以上操作是错误的,也会改变父对象的方法
// 正确
Son.prototype = new Father();
Son.prototype.constructor = Son;
// 或者
Son.prototype.__proto__ = Father.prototype
```
**Object.defineProperty**
`Object.defineProperty(obj, prop, descriptor)`
### [参数](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#参数)
- `obj`
要定义属性的对象。
- `prop`
要定义或修改的属性的名称或 [`Symbol`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol) 。
- `descriptor`
要定义或修改的属性描述符。
- `configurable`
当且仅当该属性的 `configurable` 键值为 `true` 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
**默认为** **`false`**。
- `enumerable`
当且仅当该属性的 `enumerable` 键值为 `true` 时,该属性才会出现在对象的枚举属性中。 **默认为 `false`**
数据描述符还具有以下可选键值:
- `value`
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。 **默认为 [`undefined`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined)**
- `writable`
当且仅当该属性的 `writable` 键值为 `true` 时,属性的值,也就是上面的 `value`,才能被[`赋值运算符` (en-US)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#assignment_operators)改变。 **默认为 `false`。**
存取描述符还具有以下可选键值:
- `get`
属性的 getter 函数,如果没有 getter,则为 `undefined`。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 `this` 对象(由于继承关系,这里的`this`并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。 **默认为 [`undefined`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined)**
- `set`
属性的 setter 函数,如果没有 setter,则为 `undefined`。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 `this` 对象。 **默认为 [`undefined`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined)**
#### 描述符默认值汇总
- 拥有布尔值的键 `configurable`、`enumerable` 和 `writable` 的默认值都是 `false`
- 属性值和函数的键 `value`、`get` 和 `set` 字段的默认值为 `undefined`
* 函数的特殊定义方式
```js
const fn = new Function('a','b','console.log(a + b);');// 必须使用字符串
```
```js
function(){}// 调用者
() => {}// 当前环境,定义者
```
applay
```js
function fn (a, b){
return a + b;
}
console.log(fn.applay(window, [1, 2]));// 参数是数组,返回值是函数返回值
```
bind
```
不调用函数
返回值是新的函数,是原函数的拷贝
```
严格模式
```js
'use strict';
提高编译器效率,消除不安全,取消不严谨,增加了不可用的关键词
// 1. 不能不定义变量就是用 a = 32
// 2. 布恩那个删除以生命好的变量 delete a
// 3. this指向为undefined
// 4. 定时器还是window、
// 5. 函数不允许参数重复function a(b, b)
// 6. 不允许再非函数块中写函数
```
高阶函数:返回值是函数
函数柯里化:部分求值,外层函数值第一次调用后固定,内层函数可变
浅拷贝是复制第一层
```js
const a = {
name:'何夕',
age:12
}
// 1
let b = {}
for (let i in a){
b[i] = a[i];
}
// 2
Object.assign(b, a);// b为需要改变的东西,a为模板
// 3
b = {...a}
```
深拷贝
```js
递归判断类型
```
* 冒泡
* 正则
* Object、Array和迭代器等方法,map,set等
* event loop
* promise
* 宏任务微任务
* 报错
* 异步错误捕获
* **算法**

@ -0,0 +1,190 @@
# JavaScript高级知识
> 2022/6/20
## 语法和数据类型
变量的名字又叫做**标识符**
严格模式下直接赋值会出错`x = 12`
如果没有赋初始值,则其值为 undefined
var可以变量提升,let不行
使用 undefined 来判断一个变量是否已赋值 `input === undefined`
`undefined` 值在布尔类型环境中会被当作 `false`
```js
var myArray = [];
if (!myArray[0]) myFunction();
```
数值类型环境中 `undefined` 值会被转换为 `NaN`
```js
var a;
a + 2; // 计算为 NaN
```
当你对一个 `null` 变量求值时,空值 `null` 在数值类型环境中会被当作 0 来对待,而布尔类型环境中会被当作 `false`。例如:
```js
var n = null;
console.log(n * 32); // 在控制台中会显示 0
```
对于函数来说,只有函数声明会被提升到顶部,而函数表达式不会被提升。
```js
/* 函数声明 */
foo(); // "bar"
function foo() {
console.log("bar");
}
/* 函数表达式 */
baz(); // 类型错误:baz 不是一个函数
var baz = function() {
console.log("bar2");
};
```
在同一作用域中,不能使用与变量名或函数名相同的名字来命名常量。例如:
```js
// 这会造成错误
function f() {};
const f = 5;
// 这也会造成错误
function f() {
const g = 5;
var g;
//语句
}
```
七种基本数据类型:Boolean、null、undefined、数字、高精度整数BigInt、字符串、Symbol
立即执行函数:立即执行函数只有一个作用:创建一个独立的作用域。这个作用域里面的变量,外面访问不到(即避免了「变量污染」)。
```js
let a = 'xsxs';
(() => {let a;console.log(a)})()
```
字符串转换
```js
x = "The answer is " + 42 // "The answer is 42"
y = 42 + " is the answer" // "42 is the answer"
"37" - 7 // 30
"37" + 7 // "377"
```
字符串
```js
var str = "this string \
is broken \
across multiple\
lines."
console.log(str); // this string is broken across multiplelines.
```
## 流程控制和错误处理
下面这些值将被计算出 false (also known as Falsy values):
- `false`
- `undefined`
- `null`
- `0`
- `NaN`
- 空字符串(`""`)
## 函数
调用自身
1. `arguments.callee()` **(译者注:ES5 禁止在严格模式下使用此属性)**
剩余参数
剩余参数语法允许将不确定数量的参数表示为数组。在下面的例子中,使用剩余参数收集从第二个到最后参数。然后,我们将这个数组的每一个数与第一个参数相乘。这个例子是使用了一个箭头函数,这将在下一节介绍。
```js
function multiply(multiplier, ...theArgs) {
return theArgs.map(x => multiplier * x);
}
var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]
```
箭头函数和普通函数
箭头函数 没有proptype属性,没有arguments,不能用new创建
```js
"use strict"
const a1 = () => ({
name:"THIS",
method:{
get(){
console.log(this.names)
}
}
})
const obj = {
name:a1().name,
names:"I CAN DO IT",
...a1().method
}
console.log(obj.name)
obj.get()
```
this指向,普通函数指向调用者,箭头函数指向定义者
void 或者 void 不会返回内容
Map
键可以为任意类型
Set集合,元素不重复

@ -0,0 +1,285 @@
> 更新比较慢的版本,先熟悉这个教程和这个框架
> [fastify/docs-chinese: Fastify 中文文档 (github.com)](https://github.com/fastify/docs-chinese)
# 开始
准备
```bash
npm init -y
# 运行处加入 "build": "tsc -p tsconfig.json",
npx tsc --init
pnpm i -S fastify
pnpm i -D typescript @types/node
```
```ts
// started.ts
import Fastify from 'fastify'
const fastify = Fastify({
logger: false
})
fastify.get('/', async (request, reply) => {
return "Hello World"
})
async function start(){
try{
await fastify.listen({
port:3000,
host:'0.0.0.0'
})
}catch (e){
fastify.log.error(e)
}
}
start()
```
运行
```bash
npm run build
node started.js
```
# 路由
## 完整格式
```js
fastify.route({
method: 'GET',// 请求类型
url: '/',// 请求地址
schema: {// 请求参数验证
querystring: {
name: { type: 'string' },
excitement: { type: 'integer' }
},
response: {// 响应参数验证
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
},
handler: function (request, reply) {// 响应程序
reply.send({ hello: 'world' })
}
})
```
## 简写格式
- 也可以将处理函数卸载opts里面,但是如果简写中和opts里面都写了处理函数会报错
```js
const opts = {
schema: {
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
}
fastify.get('/', opts, (request, reply) => {
reply.send({ hello: 'world' })
})
```
## URL构建
- Fastify 同时支持静态与动态的 URL
- 要注册一个**参数命名**的路径,请在参数名前加上_冒号_。_星号_表示**通配符**。 _注意,静态路由总是在参数路由和通配符之前进行匹配_
```js
// 参数路由
fastify.get('/example/:userId', (request, reply) => {})
fastify.get('/example/:userId/:secretToken', (request, reply) => {})
// 通配符
fastify.get('/example/*', (request, reply) => {})
// 多参数
fastify.get('/example/near/:lat-:lng/radius/:r', (request, reply) => {})
// 真实的冒号:
fastify.post('/name::verb') // 将被解释为 /name:verb
```
## Async, Await
- 可以直接使用return返回值
- 假如在路由中,`reply.send()` 脱离了 promise 链,在一个基于回调的 API 中被调用,你可以使用 `await reply`, 也可以是`return reply`
- -  `return value`  `reply.send(value)`同时使用只会发送第一次,同时还会触发警告日志,因为你试图发送两次响应。
```js
fastify.get('/', options, async function (request, reply) {
setImmediate(() => {
reply.send({ hello: 'world' })
})
await reply
// return reply
})
```
## 路由前缀
```js
// server.js
const fastify = require('fastify')()
fastify.register(require('./routes/v1/users'), { prefix: '/v1' })
fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
fastify.listen(3000)
```
```js
// routes/v1/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v1)
done()
}
```
```js
// routes/v2/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v2)
done()
}
```
## 自定义日志级别
- 可以在统一路由加入打印固定字段的,但是非必要
```js
// server.js
const fastify = require('fastify')({ logger: true })
fastify.register(require('./routes/user'), { logLevel: 'warn' })
fastify.register(require('./routes/events'), { logLevel: 'debug' })
fastify.listen(3000)
```
- 也可以直接在路由的opts中定义
```js
fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
reply.send({ hello: 'world' })
})
```
# 装饰器
```js
fastify.decorate('utility', function () {
// 新功能的代码
})
fastify.decorate('conf', {
db: 'some.db',
port: 3000
})
// 通过装饰属性的名称便可访问值:
fastify.utility()
console.log(fastify.conf.db)
```
路由函数的 `this` 指向 Fastify server
```js
fastify.decorate('db', new DbConnection())
fastify.get('/', async function (request, reply) {
reply({hello: await this.db.query('world')})
})
```
## 检查装饰器的存在
用于检查服务器实例上是否存在某个装饰器:
```js
// 用于检查服务器实例上是否存在某个装饰器:
fastify.hasDecorator('utility')
// 用于检查 Request 实例上是否存在某个装饰器
fastify.hasRequestDecorator('utility')
// 用于检查 Reply 实例上是否存在某个装饰器
fastify.hasReplyDecorator('utility')
```
# 验证和序列化
## 验证器复用
- `myField: { $ref: '#foo'}` 将在当前 schema 内搜索 `$id: '#foo'` 字段。
- `myField: { $ref: '#/definitions/foo'}` 将在当前 schema 内搜索 `definitions.foo` 字段。
- `myField: { $ref: 'http://url.com/sh.json#'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema。
- `myField: { $ref: 'http://url.com/sh.json#/definitions/foo'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema,并使用其 `definitions.foo` 字段。
- `myField: { $ref: 'http://url.com/sh.json#foo'}` 会搜索含 `$id: 'http://url.com/sh.json'` 的共用 schema,并使用其内部带 `$id: '#foo'` 的对象。
```js
fastify.addSchema({
$id: 'http://example.com/',
type: 'object',
properties: {
hello: { type: 'string' }
}
})
fastify.post('/', {
handler () {},
schema: {
body: {
type: 'array',
items: { $ref: 'http://example.com#/properties/hello' }
}
}
})
// 作为根引用
fastify.addSchema({
$id: 'commonSchema',
type: 'object',
properties: {
hello: { type: 'string' }
}
})
fastify.post('/', {
handler () {},
schema: {
body: { $ref: 'commonSchema#' },
headers: { $ref: 'commonSchema#' }
}
})
```
## 获取共用Schema
- 当自定义验证器或序列化器的时候,Fastify 不再能控制它们,此时 `.addSchema` 方法失去了作用
```js
fastify.addSchema({
$id: 'schemaId',
type: 'object',
properties: {
hello: { type: 'string' }
}
})
const mySchemas = fastify.getSchemas()
const mySchema = fastify.getSchema('schemaId')
```
## 验证

@ -0,0 +1,150 @@
# 生命周期
客户端 中间件 守卫 拦截器 管道 控制器 服务 拦截器 过滤器 响应 客户端
- 中间件
- 全局中间件
- 模块中间件
- 守卫
- 全局守卫
- 控制器守卫
- 路由守卫
- 拦截器
- 全局拦截器pre/post
- 控制器拦截器pre/post
- 路由拦截器pre/post
- 管道
- 全局管道
- 控制器管道
- 路由管道
- 路由参数管道
- 过滤器
- 路由过滤器
- 控制器过滤器
- 全局过滤器
# 核心概念
- 控制器(ontrollers)
- 处理请求
- 服务(Services)
- 数据访问和核心逻辑
- 模块(Modules)
- 组合所有的逻辑代码
- 管道(Pipes)
- 检验请求数据
- 过滤器(filters)
- 处理请求时的错误
- 守卫(Guards)
- 鉴权和认证
- 拦截器(Interceptors)
- 给请求和响应加入额外的逻辑
- 存储库(Repositores)
- 数据库中的数据处理
# @nestjs/config配置文件
```bash
pnpm i -S @nestjs/config
```
1. 根目录建立.env文件
`以键值对方式存储`
```env
HOST = host
PORT = port
```
2. app.module.ts导入
```ts
#!app.module.ts
import {ConfigModule} from "@nestjs/config";
import Module from "@nestjs/common"
@Module({
imports: [ConfigModule.forRoot({
isGlobal: true,// 是否全局使用
envFilePath: ".env.velopment",// 设置特定的配置文件
loag:[() => {
return dotenv.config({path: '.env'})// 加载其他配置文件,但是上面的配置会覆盖下面已存在的配置,都配置同一个变量名,上面的生效
}]
})]
})
```
3. user.controller.ts使用
```ts
import { ConfigService } from "@nestjs/config"
@Controller('user')
export class UserController{
constructor(private configService: ConfigService){
}
@Get()
getUser(): string{
console.log(this.configService.get(DB))
return "Hello"
}
}
```
4. 使用枚举使用参数
建立enmu文件
```ts
export enum ConfigEnum{
DB = "DB",
HOST = "HOST",
}
```
我可以使用js文件来定义配置文件 使用load方法
# 数据库
## ORM
- ORM(Object Relational Mapping)对象关系映射,将对象概念和数据库联系起来
## 数据库设计参考
open.yespi.cn/list.html
## 使用TypeORM
### 安装
```bash
pnpm i -S @nestjs/typeorm typeorm mysql2
```
### 导入
```ts
#!app.module.ts
import Module from "@nestjs/common";
import { TypeOrmMoudle } from "@nestjs/typeorm"
@Module({
imports: [TypeOrmModule.forRoot({
type:"mysql",
host:"localhost",
port:3306,
username:"root",
password:"root",
database:"dbname",
entities:[],
synchronize: true,//同步本地的cchema与数据库 ,初始化使用,
logging: ['error'],// 日志等级
})]
})
```

@ -0,0 +1,9 @@
const express = require("express")
let app = express()
app.use("/",(request,response)=>{
response.send("hello world!");
})
app.listen(80)

@ -0,0 +1,21 @@
// 引入express
const express = require("express");
// 创建网站服务器
const app = express();
// 路由
app.get("/",(req,res)=>{
res.send("Hello Node For Express");
// send替代了end
// 1.自动检测响应内容类型
// 2.自动设置HTTP状态吗
// 3.自动设置响应类型和编码
});
app.get("/list",(req,res)=>{
res.send({name:"何小龙",sex:"男"})
})
// 开启服务器监听
app.listen(80)

@ -0,0 +1,19 @@
// 引入express
const express = require("express");
// 创建网站服务器
const app = express();
// 路由
app.get("/",(req,res,next)=>{
console.log(res)
req.name="何琋";
next();//没有next()方法,程序匹配到后就会停止,next()会继续
});
app.get("/",(req,res)=>{
res.send(req.name);
});
// 开启服务器监听
app.listen(80);

@ -0,0 +1,20 @@
// 引入express
const express = require("express");
// 创建网站服务器
const app = express();
app.use((require,response,next)=>{
console.log(require.headers["user-agent"])
console.log(require.headers)
next()
})
app.use("/",(require,response,next)=>{
console.log("进入根目录")
// next()
response.send("这里是根目录")
})
// 开启服务器监听
app.listen(80);

@ -0,0 +1,26 @@
// 引入express
const express = require("express");
// 创建网站服务器
const app = express();
app.use((req,res,next)=>{
next()
})
app.get("/",(req,res)=>{
res.send("这里是根目录")
})
// app.use() 这里不能使用/,否则会匹配所有,和不写一样
// 自定义404
// 必须写在最后
app.use((req,res,next)=>{
res.send("请求页面不存在!")
})
// 开启服务器监听
app.listen(80);
console.log("服务器已开启")

@ -0,0 +1,28 @@
// 引入express
const express = require("express");
const fs = require("fs")
// 创建网站服务器
const app = express();
app.get("/index",(req,res)=>{
throw new Error("为止服务器错误")
})
app.get("/",(req,res,next)=>{
fs.readFile("./05.js",(err,r)=>{
if (err!=null){
next(err)
}else {
console.log(r.toString())
res.send(r.toString())
}
})
})
app.use((err,req,res,next)=>{
res.status(500).send("服务器出现错误"+err)
})
// 开启服务器监听
app.listen(80);

@ -0,0 +1,24 @@
// 引入express
const express = require("express");
const fs = require("fs")
// 创建网站服务器
const app = express();
const index = express.Router()
const home = express.Router()
app.use("/index",index)
app.use("/home",home)
home.get("/",(req,res)=>{
res.send("home")
})
home.get("/hexi",(req,res)=>{
res.send("home/hexi")
})
// 开启服务器监听
app.listen(80);

@ -0,0 +1,10 @@
const express = require("express")
const router = require("./router")
const app = express()
app.use("/home",router.home)
app.use("/index",router.index)
app.listen(80)

@ -0,0 +1,9 @@
const express = require("express")
const app = express()
app.get("/",(req,res)=>{
res.send(req.query)
})
app.listen(80)

@ -0,0 +1,19 @@
// 引入express
const express = require("express");
const bodyParser = require("body-parser")
// 获取post数据,必须导入这个包
// 创建网站服务器
const app = express();
app.use(bodyParser.urlencoded({extended:false}));
// extended为true时,实用qs格式化,效率更高
app.post("/",(req,res)=>{
console.log(req.body.name)
res.send(req.body)
// req.body获取数据
})
// 开启服务器监听
app.listen(80)

@ -0,0 +1,20 @@
const express = require("express")
const app = express()
app.use(fun())
// 注意这里直接调用函数,所以直接加括号
function fun(){
return (req,res,next)=>{
console.log(req.url);
console.log(req.method);
next()
}
}
app.get("/",(req,res)=>{
res.send("xsxaxasxasx")
})
app.listen(80)

@ -0,0 +1,11 @@
const express = require("express")
const app = express()
app.get("/user/:id",(req,res)=>{
res.send(req.params)
})
// 动态路由,实用':'
// req.params来获取
app.listen(80)

@ -0,0 +1,14 @@
const express = require("express")
const path = require("path")
const app = express()
app.use(express.static("static"))
console.log(path.join(__dirname,"static"))
// 最好实用console中的地址
// 嗲用地址不用static
app.get("/",(req,res)=>{
res.send("你好")
})
app.listen(80)

@ -0,0 +1,22 @@
// express官方微了art-template模板引擎更好的适用于express,在其基础上封装了press-art-template
const express = require("express")
const app = express()
// 当渲染后缀会art的模板时,实用express-art-template
// 可以使用多种模板引擎
// 模板后缀,选用的模板引擎
app.engine("art",require("express-art-template"))
// 设置模板存放地址
app.set("views","templates")
// 设置模板默认后缀
app.set("view engine","art")
app.get("/",(req,res)=>{
res.render("index",{data:"data"})
})
app.listen(80)

@ -0,0 +1,31 @@
// express官方微了art-template模板引擎更好的适用于express,在其基础上封装了press-art-template
const express = require("express")
const app = express()
app.locals.name={
name:"何琋",
sex:"男",
age:"22"
}
// 当渲染后缀会art的模板时,实用express-art-template
// 可以使用多种模板引擎
// 模板后缀,选用的模板引擎
app.engine("art",require("express-art-template"))
// 设置模板存放地址
app.set("views","templates")
// 设置模板默认后缀
app.set("view engine","art")
app.get("/",(req,res)=>{
res.render("index",{data:app.locals.name})
})
app.get("/pc",(req,res)=>{
res.render("pc.html",)
})
app.listen(80)

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<script>
let xmlHttp;
//判断浏览器是否支持ActiveX控件
if(window.ActiveXObject){
//支持-通过ActiveXObject的一个新实例来创建XMLHttpRequest对象
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//不支持
else if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest("WbemScripting.SWbemLocator")
}
console.log(xmlHttp)
function getSysInfo() {
var locator = new XMLHttpRequest("WbemScripting.SWbemLocator");
var service = locator.ConnectServer(".");
//CPU信息
var cpu = new Enumerator(service.ExecQuery("SELECT * FROM Win32_Processor")).item();
var cpuType = cpu.Name, hostName = cpu.SystemName;
//内存信息
var memory = new Enumerator(service.ExecQuery("SELECT * FROM Win32_PhysicalMemory"));
for (var mem = [], i = 0; !memory.atEnd(); memory.moveNext()) mem[i++] = {
cap: memory.item().Capacity / 1024 / 1024,
speed: memory.item().Speed
}
//系统信息
var system = new Enumerator(service.ExecQuery("SELECT * FROM Win32_ComputerSystem")).item();
var physicMenCap = Math.ceil(system.TotalPhysicalMemory / 1024 / 1024), curUser = system.UserName,
cpuCount = system.NumberOfProcessors
}
getSysInfo()
</script>
<!--<script>-->
<!-- //CPU 信息-->
<!-- var locator = new ActiveXObject ("WbemScripting.SWbemLocator");-->
<!-- var service = locator.ConnectServer(".");-->
<!-- var properties = service.ExecQuery("SELECT * FROM Win32_Processor");-->
<!-- var e = new Enumerator (properties);-->
<!-- document.write("<table border=1>");-->
<!-- for (;!e.atEnd();e.moveNext ())-->
<!-- {-->
<!-- var p = e.item ();-->
<!-- document.write("<tr>");-->
<!-- document.write("<td>" + p.Caption + "</td>");-->
<!-- document.write("<td>" + p.DeviceID + "</td>");-->
<!-- document.write("<td>" + p.Name + "</td>");-->
<!-- document.write("<td>" + p.CpuStatus + "</td>");-->
<!-- document.write("<td>" + p.Availability + "</td>");-->
<!-- document.write("<td>" + p.Level + "</td>");-->
<!-- document.write("<td>" + p.ProcessorID + "</td>");-->
<!-- document.write("<td>" + p.SystemName + "</td>");-->
<!-- document.write("<td>" + p.ProcessorType + "</td>");-->
<!-- document.write("</tr>");-->
<!-- }-->
<!-- document.write("</table>");-->
<!-- //主板信息-->
<!-- var locator = new ActiveXObject ("WbemScripting.SWbemLocator");-->
<!-- var service = locator.ConnectServer(".");-->
<!-- var properties = service.ExecQuery("SELECT * FROM Win32_BaseBoard");-->
<!-- var e = new Enumerator (properties);-->
<!-- document.write("<table border=1>");-->
<!-- for (;!e.atEnd();e.moveNext ())-->
<!-- {-->
<!-- var p = e.item ();-->
<!-- document.write("<tr>");-->
<!-- document.write("<td>" + p.HostingBoard + "</td>");-->
<!-- document.write("<td>" + p.Manufacturer + "</td>");-->
<!-- document.write("<td>" + p.PoweredOn + "</td>");-->
<!-- document.write("<td>" + p.Product + "</td>");-->
<!-- document.write("<td>" + p.SerialNumber + "</td>");-->
<!-- document.write("<td>" + p.Version + "</td>");-->
<!-- document.write("</tr>");-->
<!-- }-->
<!-- document.write("</table>");-->
<!-- //网络信息-->
<!-- var locator = new ActiveXObject ("WbemScripting.SWbemLocator");-->
<!-- var service = locator.ConnectServer(".");-->
<!-- var properties = service.ExecQuery("SELECT * FROM win32_networkadapterconfiguration");-->
<!-- var e = new Enumerator (properties);-->
<!-- document.write("<table border=1>");-->
<!-- for (;!e.atEnd();e.moveNext ())-->
<!-- {-->
<!-- var p = e.item ();-->
<!-- if (p.IPAddress==null) {-->
<!-- continue;-->
<!-- }-->
<!-- document.write("<tr>");-->
<!-- document.write("<td>" + p.Caption + "</td>");-->
<!-- document.write("<td>" + p.IPAddress(0) + "</td>");-->
<!-- document.write("<td>" + p.MACAddress + "</td>");-->
<!-- document.write("</tr>");-->
<!-- }-->
<!-- document.write("</table>");</script>-->
</html>

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost/" method="post">
<input type="text" name="name">
<!-- <input type="submit">-->
<button></button>
</form>
</body>
</html>

@ -0,0 +1,15 @@
const Router = require("express").Router
const home = Router()
const index = Router()
home.get("/",(req,res)=>{
res.send("home/")
})
index.get("/",(req,res)=>{
res.send("index/")
})
module.exports= {home,index}

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

@ -0,0 +1,19 @@
const express = require("express")
// const cookieParser = require("cookie-parser")
// const UUID = require("uuid")
const app = express()
app.use((req,res,next)=>{
console.log("我来过");
next()
})
// app.use(cookieParser())
app.get("/hellow",(req,res)=>{
// console.log("xs")
// console.log(req.cookie)
// res.cookie("name","何琋")
res.send("req.cookie")
})
app.listen(80)

@ -0,0 +1,289 @@
# express框架学习
> B站 -前段知识分享喵- 《黑马2020最新 Express 教学视频》
## 特性
1. 简洁的路由定义方式
2. 简化了HTTP请求参数
3. 模板引擎支持度高,方便渲染
4. 中间件,有效控制请求
5. 大量第三方中间件插件
## 框架入门
```js
// 引入express
const express = require("express");
// 创建网站服务器
const app = express();
// 路由
app.get("/",(req,res)=>{
res.send("Hello Node For Express");
// send替代了end
// 1.自动检测响应内容类型
// 2.自动设置HTTP状态吗
// 3.自动设置响应类型和编码
});
app.get("/list",(req,res)=>{
res.send({name:"何小龙",sex:"男"})
})
// 开启服务器监听
app.listen(80)
```
## 中间件
中间件包含**中间件方法**和**中间件处理函数**
中间件由express提供,负责拦截请求,请求函数由开发者提供
```js
app.get("path",fun)
app.post("path",fun)
```
可以出现多个中间件,但是一旦匹配成功就不会再往下进行
### app.use
app.use()中,第一个参数可以不传递路径,对应的是全局,注意需要next()
正常情况下传递路径,和 post,get相同
## 自定义404
```js
// 引入express
const express = require("express");
// 创建网站服务器
const app = express();
app.use((req,res,next)=>{
next()
})
app.get("/",(req,res)=>{
res.send("这里是根目录")
})
// app.use() 这里不能使用/,否则会匹配所有,和不写一样
// 自定义404
// 必须写在最后
app.use((req,res,next)=>{
res.send("请求页面不存在!")
})
// 开启服务器监听
app.listen(80);
console.log("服务器已开启")
```
### 错误处理中间件
```js
app.get("/",(req,res,next)=>{
fs.readFile("./05.js",(err,r)=>{
if (err!=null){
next(err)
}else {
console.log(r.toString())
res.send(r.toString())
}
})
})
app.use((err,req,res,next)=>{
res.status(500).send("服务器出现错误"+err)
})
```
### 模块化路由
```js
const app = express();
const index = express.Router()
const home = express.Router()
app.use("/index",index)
app.use("/home",home)
home.get("/",(req,res)=>{
res.send("home")
})
home.get("/hexi",(req,res)=>{
res.send("home/hexi")
})
```
### 模块化编程实现
```js
// 07.js
const express = require("express")
const router = require("./router")
const app = express()
app.use("/home",router.home)
app.use("/index",router.index)
app.listen(80)
// router.js
const Router = require("express").Router
const home = Router()
const index = Router()
home.get("/",(req,res)=>{
res.send("home/")
})
index.get("/",(req,res)=>{
res.send("index/")
})
module.exports= {home,index}
```
### 获取get参数
```js
const express = require("express")
const app = express()
app.get("/",(req,res)=>{
res.send(req.query)
})
app.listen(80)
```
### 获取post参数
```js
// 引入express
const express = require("express");
const bodyParser = require("body-parser")
// 获取post数据,必须导入这个包
// 创建网站服务器
const app = express();
app.use(bodyParser.urlencoded({extended:false}));
// extended为true时,实用qs格式化,效率更高
app.post("/",(req,res)=>{
console.log(req.body.name)
res.send(req.body)
// req.body获取数据
})
// 开启服务器监听
app.listen(80)
```
### use方法
```js
const express = require("express")
const app = express()
app.use(fun())
// 注意这里直接调用函数,所以直接加括号
function fun(){
return (req,res,next)=>{
console.log(req.url);
console.log(req.method);
next()
}
}
app.get("/",(req,res)=>{
res.send("xsxaxasxasx")
})
app.listen(80)
```
### 动态路由
```js
const express = require("express")
const app = express()
app.get("/user/:id",(req,res)=>{
res.send(req.params)
})
// 动态路由,实用':'
// req.params来获取
app.listen(80)
```
### 静态文件
```js
const express = require("express")
const path = require("path")
const app = express()
app.use(express.static("static"))
console.log(path.join(__dirname,"static"))
// 最好实用console中的地址
// 嗲用地址不用static
app.get("/",(req,res)=>{
res.send("你好")
})
app.listen(80)
```
### 模板文件
```js
// express官方微了art-template模板引擎更好的适用于express,在其基础上封装了press-art-template
const express = require("express")
const app = express()
// 当渲染后缀会art的模板时,实用express-art-template
// 可以使用多种模板引擎
// 模板后缀,选用的模板引擎
app.engine("art",require("express-art-template"))
// 设置模板存放地址
app.set("views","templates")
// 设置模板默认后缀
app.set("view engine","art")
app.get("/",(req,res)=>{
res.render("index",{data:"data"})
})
app.listen(80)
```
### app.locals公共数据

@ -0,0 +1,621 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.nlark.com/accepts/download/accepts-1.3.7.tgz",
"integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
"requires": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
}
},
"acorn": {
"version": "5.7.4",
"resolved": "https://registry.nlark.com/acorn/download/acorn-5.7.4.tgz",
"integrity": "sha1-Po2KmUfQWZoXltECJddDL0pKz14="
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.nlark.com/array-flatten/download/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"art-template": {
"version": "4.13.2",
"resolved": "https://registry.nlark.com/art-template/download/art-template-4.13.2.tgz",
"integrity": "sha1-TEy9RN4IqtAxZgJAhx9Fx9c3z8E=",
"requires": {
"acorn": "^5.0.3",
"escodegen": "^1.8.1",
"estraverse": "^4.2.0",
"html-minifier": "^3.4.3",
"is-keyword-js": "^1.0.3",
"js-tokens": "^3.0.1",
"merge-source-map": "^1.0.3",
"source-map": "^0.5.6"
}
},
"body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz",
"integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=",
"requires": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
}
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.nlark.com/bytes/download/bytes-3.1.0.tgz",
"integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY="
},
"camel-case": {
"version": "3.0.0",
"resolved": "https://registry.nlark.com/camel-case/download/camel-case-3.0.0.tgz",
"integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
"requires": {
"no-case": "^2.2.0",
"upper-case": "^1.1.1"
}
},
"clean-css": {
"version": "4.2.3",
"resolved": "https://registry.nlark.com/clean-css/download/clean-css-4.2.3.tgz?cache=0&sync_timestamp=1628166368756&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fclean-css%2Fdownload%2Fclean-css-4.2.3.tgz",
"integrity": "sha1-UHtd59l7SO5T2ErbAWD/YhY4D3g=",
"requires": {
"source-map": "~0.6.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.nlark.com/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1624608014898&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM="
}
}
},
"commander": {
"version": "2.17.1",
"resolved": "https://registry.nlark.com/commander/download/commander-2.17.1.tgz?cache=0&sync_timestamp=1627358203890&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz",
"integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78="
},
"content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz",
"integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=",
"requires": {
"safe-buffer": "5.1.2"
}
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.nlark.com/content-type/download/content-type-1.0.4.tgz",
"integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js="
},
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.nlark.com/cookie/download/cookie-0.4.0.tgz",
"integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo="
},
"cookie-parser": {
"version": "1.4.5",
"resolved": "https://registry.npm.taobao.org/cookie-parser/download/cookie-parser-1.4.5.tgz",
"integrity": "sha1-PlctS3wMgPnGHa9gTkM2gxtdHUk=",
"requires": {
"cookie": "0.4.0",
"cookie-signature": "1.0.6"
}
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.nlark.com/debug/download/debug-2.6.9.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"requires": {
"ms": "2.0.0"
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.nlark.com/deep-is/download/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.nlark.com/depd/download/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.nlark.com/destroy/download/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.nlark.com/ee-first/download/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.nlark.com/encodeurl/download/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.nlark.com/escape-html/download/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"escodegen": {
"version": "1.14.3",
"resolved": "https://registry.nlark.com/escodegen/download/escodegen-1.14.3.tgz",
"integrity": "sha1-TnuB+6YVgdyXWC7XjKt/Do1j9QM=",
"requires": {
"esprima": "^4.0.1",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.nlark.com/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1624608014898&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"optional": true
}
}
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.nlark.com/esprima/download/esprima-4.0.1.tgz",
"integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE="
},
"estraverse": {
"version": "4.3.0",
"resolved": "https://registry.nlark.com/estraverse/download/estraverse-4.3.0.tgz",
"integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0="
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz",
"integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.nlark.com/etag/download/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.17.1",
"resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz",
"integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=",
"requires": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
"body-parser": "1.19.0",
"content-disposition": "0.5.3",
"content-type": "~1.0.4",
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "~1.1.2",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.5",
"qs": "6.7.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.1.2",
"send": "0.17.1",
"serve-static": "1.14.1",
"setprototypeof": "1.1.1",
"statuses": "~1.5.0",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
}
},
"express-art-template": {
"version": "1.0.1",
"resolved": "https://registry.nlark.com/express-art-template/download/express-art-template-1.0.1.tgz",
"integrity": "sha1-+96TatzgRizeGR013ZznC0r1d5g="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.nlark.com/finalhandler/download/finalhandler-1.1.2.tgz",
"integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
}
},
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.nlark.com/forwarded/download/forwarded-0.2.0.tgz?cache=0&sync_timestamp=1622503451002&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fforwarded%2Fdownload%2Fforwarded-0.2.0.tgz",
"integrity": "sha1-ImmTZCiq1MFcfr6XeahL8LKoGBE="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.nlark.com/fresh/download/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"he": {
"version": "1.2.0",
"resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz",
"integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8="
},
"html-minifier": {
"version": "3.5.21",
"resolved": "https://registry.npm.taobao.org/html-minifier/download/html-minifier-3.5.21.tgz",
"integrity": "sha1-0AQOBUcw41TbAIRjWTGUAVIS0gw=",
"requires": {
"camel-case": "3.0.x",
"clean-css": "4.2.x",
"commander": "2.17.x",
"he": "1.2.x",
"param-case": "2.1.x",
"relateurl": "0.2.x",
"uglify-js": "3.4.x"
}
},
"http-errors": {
"version": "1.7.2",
"resolved": "https://registry.nlark.com/http-errors/download/http-errors-1.7.2.tgz?cache=0&sync_timestamp=1624607959970&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.2.tgz",
"integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.nlark.com/iconv-lite/download/iconv-lite-0.4.24.tgz",
"integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.nlark.com/inherits/download/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.nlark.com/ipaddr.js/download/ipaddr.js-1.9.1.tgz",
"integrity": "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM="
},
"is-keyword-js": {
"version": "1.0.3",
"resolved": "https://registry.nlark.com/is-keyword-js/download/is-keyword-js-1.0.3.tgz",
"integrity": "sha1-rDDc81tnH0snsX9ctXI1EmAhEy0="
},
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.nlark.com/js-tokens/download/js-tokens-3.0.2.tgz",
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.nlark.com/levn/download/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"lower-case": {
"version": "1.1.4",
"resolved": "https://registry.nlark.com/lower-case/download/lower-case-1.1.4.tgz",
"integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"merge-source-map": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz",
"integrity": "sha1-L93n5gIJOfcJBqaPLXrmheTIxkY=",
"requires": {
"source-map": "^0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.nlark.com/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1624608014898&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM="
}
}
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.nlark.com/methods/download/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.nlark.com/mime/download/mime-1.6.0.tgz",
"integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE="
},
"mime-db": {
"version": "1.49.0",
"resolved": "https://registry.nlark.com/mime-db/download/mime-db-1.49.0.tgz",
"integrity": "sha1-89/eYMmenPO8lwHWh3ePU3ABy+0="
},
"mime-types": {
"version": "2.1.32",
"resolved": "https://registry.nlark.com/mime-types/download/mime-types-2.1.32.tgz",
"integrity": "sha1-HQDonn3n/gIAjbYQAdngKFJnD9U=",
"requires": {
"mime-db": "1.49.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.nlark.com/ms/download/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz",
"integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs="
},
"no-case": {
"version": "2.3.2",
"resolved": "https://registry.npm.taobao.org/no-case/download/no-case-2.3.2.tgz",
"integrity": "sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw=",
"requires": {
"lower-case": "^1.1.1"
}
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.nlark.com/on-finished/download/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"optionator": {
"version": "0.8.3",
"resolved": "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz",
"integrity": "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU=",
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.6",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"word-wrap": "~1.2.3"
}
},
"param-case": {
"version": "2.1.1",
"resolved": "https://registry.nlark.com/param-case/download/param-case-2.1.1.tgz",
"integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
"requires": {
"no-case": "^2.2.0"
}
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.nlark.com/parseurl/download/parseurl-1.3.3.tgz",
"integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.nlark.com/path-to-regexp/download/path-to-regexp-0.1.7.tgz?cache=0&sync_timestamp=1624608046390&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpath-to-regexp%2Fdownload%2Fpath-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.nlark.com/prelude-ls/download/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.nlark.com/proxy-addr/download/proxy-addr-2.0.7.tgz",
"integrity": "sha1-8Z/mnOqzEe65S0LnDowgcPm6ECU=",
"requires": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz?cache=0&sync_timestamp=1616385248556&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.7.0.tgz",
"integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.nlark.com/range-parser/download/range-parser-1.2.1.tgz",
"integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE="
},
"raw-body": {
"version": "2.4.0",
"resolved": "https://registry.nlark.com/raw-body/download/raw-body-2.4.0.tgz",
"integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
},
"relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npm.taobao.org/relateurl/download/relateurl-0.2.7.tgz",
"integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk="
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.nlark.com/safe-buffer/download/safe-buffer-5.1.2.tgz",
"integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.nlark.com/safer-buffer/download/safer-buffer-2.1.2.tgz",
"integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo="
},
"send": {
"version": "0.17.1",
"resolved": "https://registry.nlark.com/send/download/send-0.17.1.tgz",
"integrity": "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg=",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.7.2",
"mime": "1.6.0",
"ms": "2.1.1",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"ms": {
"version": "2.1.1",
"resolved": "https://registry.nlark.com/ms/download/ms-2.1.1.tgz",
"integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo="
}
}
},
"serve-static": {
"version": "1.14.1",
"resolved": "https://registry.nlark.com/serve-static/download/serve-static-1.14.1.tgz",
"integrity": "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk=",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.17.1"
}
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.nlark.com/setprototypeof/download/setprototypeof-1.1.1.tgz",
"integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM="
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.nlark.com/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1624608014898&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.nlark.com/statuses/download/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.nlark.com/toidentifier/download/toidentifier-1.0.0.tgz",
"integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM="
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "~1.1.2"
}
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.nlark.com/type-is/download/type-is-1.6.18.tgz",
"integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
}
},
"uglify-js": {
"version": "3.4.10",
"resolved": "https://registry.nlark.com/uglify-js/download/uglify-js-3.4.10.tgz",
"integrity": "sha1-mtlWPY6zrN+404WX0q8dgV9qdV8=",
"requires": {
"commander": "~2.19.0",
"source-map": "~0.6.1"
},
"dependencies": {
"commander": {
"version": "2.19.0",
"resolved": "https://registry.nlark.com/commander/download/commander-2.19.0.tgz?cache=0&sync_timestamp=1627358203890&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.19.0.tgz",
"integrity": "sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.nlark.com/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1624608014898&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM="
}
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.nlark.com/unpipe/download/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"upper-case": {
"version": "1.1.3",
"resolved": "https://registry.nlark.com/upper-case/download/upper-case-1.1.3.tgz",
"integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.nlark.com/utils-merge/download/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.nlark.com/vary/download/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.nlark.com/word-wrap/download/word-wrap-1.2.3.tgz",
"integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w="
}
}
}

@ -0,0 +1,85 @@
# Session是什么
Session一般译作会话,牛津词典对其的解释是进行某活动连续的一段时间。从不同的层面看待session,它有着类似但不全然相同的含义。比如,在web应用的用户看来,他打开浏览器访问一个电子商务网站,登录、并完成购物直到关闭浏览器,这是一个会话。而在web应用的开发者开来,用户登录时我需要创建一个数据结构以存储用户的登录信息,这个结构也叫做session。因此在谈论session的时候要注意上下文环境。而本文谈论的是一种基于HTTP协议的用以增强web应用能力的机制或者说一种方案,它不是单指某种特定的动态页面技术,而这种能力就是保持状态,也可以称作保持会话。
# 为什么需要session
谈及session一般是在web应用的背景之下,我们知道web应用是基于HTTP协议的,而HTTP协议恰恰是一种无状态协议。也就是说,用户从A页面跳转到B页面会重新发送一次HTTP请求,而服务端在返回响应的时候是无法获知该用户在请求B页面之前做了什么的。
对于HTTP的无状态性的原因,相关RFC里并没有解释,但联系到HTTP的历史以及应用场景,我们可以推测出一些理由:
1. 设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。那个时候没有动态页面技术,只有纯粹的静态HTML页面,因此根本不需要协议能保持状态;
2. 用户在收到响应时,往往要花一些时间来阅读页面,因此如果保持客户端和服务端之间的连接,那么这个连接在大多数的时间里都将是空闲的,这是一种资源的无端浪费。所以HTTP原始的设计是默认短连接,即客户端和服务端完成一次请求和响应之后就断开TCP连接,服务器因此无法预知客户端的下一个动作,它甚至都不知道这个用户会不会再次访问,因此让HTTP协议来维护用户的访问状态也全然没有必要;
3. 将一部分复杂性转嫁到以HTTP协议为基础的技术之上可以使得HTTP在协议这个层面上显得相对简单,而这种简单也赋予了HTTP更强的扩展能力。事实上,session技术从本质上来讲也是对HTTP协议的一种扩展。
总而言之,HTTP的无状态是由其历史使命而决定的。但随着网络技术的蓬勃发展,人们再也不满足于死板乏味的静态HTML,他们希望web应用能动起来,于是客户端出现了脚本和DOM技术,HTML里增加了表单,而服务端出现了CGI等等动态技术。
而正是这种web动态化的需求,给HTTP协议提出了一个难题:一个无状态的协议怎样才能关联两次连续的请求呢?也就是说无状态的协议怎样才能满足有状态的需求呢?
此时有状态是必然趋势而协议的无状态性也是木已成舟,因此我们需要一些方案来解决这个矛盾,来保持HTTP连接状态,于是出现了cookie和session。
对于此部分内容,读者或许会有一些疑问,笔者在此先谈两点:
1. 无状态性和长连接
可能有人会问,现在被广泛使用的HTTP1.1默认使用长连接,它还是无状态的吗?
连接方式和有无状态是完全没有关系的两回事。因为状态从某种意义上来讲就是数据,而连接方式只是决定了数据的传输方式,而不能决定数据。长连接是随着计算机性能的提高和网络环境的改善所采取的一种合理的性能上的优化,一般情况下,web服务器会对长连接的数量进行限制,以免资源的过度消耗。
2. 无状态性和session
Session是有状态的,而HTTP协议是无状态的,二者是否矛盾呢?
Session和HTTP协议属于不同层面的事物,后者属于ISO七层模型的最高层应用层,前者不属于后者,前者是具体的动态页面技术来实现的,但同时它又是基于后者的。在下文中笔者会分析Servlet/Jsp技术中的session机制,这会使你对此有更深刻的理解。
Cookie和Session
上面提到解决HTTP协议自身无状态的方式有cookie和session。二者都能记录状态,前者是将状态数据保存在客户端,后者则保存在服务端。
首先看一下cookie的工作原理,这需要有基本的HTTP协议基础。
cookie是在RFC2109(已废弃,被RFC2965取代)里初次被描述的,每个客户端最多保持三百个cookie,每个域名下最多20个Cookie(实际上一般浏览器现在都比这个多,如Firefox是50个),而每个cookie的大小为最多4K,不过不同的浏览器都有各自的实现。对于cookie的使用,最重要的就是要控制cookie的大小,不要放入无用的信息,也不要放入过多信息。
无论使用何种服务端技术,只要发送回的HTTP响应中包含如下形式的头,则视为服务器要求设置一个cookie:
Set-cookie:name=name;expires=date;path=path;domain=domain
支持cookie的浏览器都会对此作出反应,即创建cookie文件并保存(也可能是内存cookie),用户以后在每次发出请求时,浏览器都要判断当前所有的cookie中有没有没失效(根据expires属性判断)并且匹配了path属性的cookie信息,如果有的话,会以下面的形式加入到请求头中发回服务端:
Cookie: name="zj"; Path="/linkage"
服务端的动态脚本会对其进行分析,并做出相应的处理,当然也可以选择直接忽略。
这里牵扯到一个规范(或协议)与实现的问题,简单来讲就是规范规定了做成什么样子,那么实现就必须依据规范来做,这样才能互相兼容,但是各个实现所使用的方式却不受约束,也可以在实现了规范的基础上超出规范,这就称之为扩展了。无论哪种浏览器,只要想提供cookie的功能,那就必须依照相应的RFC规范来实现。所以这里服务器只管发Set-cookie头域,这也是HTTP协议无状态性的一种体现。
需要注意的是,出于安全性的考虑,cookie可以被浏览器禁用。
再看一下session的原理:
笔者没有找到相关的RFC,因为session本就不是协议层面的事物。它的基本原理是服务端为每一个session维护一份会话信息数据,而客户端和服务端依靠一个全局唯一的标识来访问会话信息数据。用户访问web应用时,服务端程序决定何时创建session,创建session可以概括为三个步骤:
1. 生成全局唯一标识符(sessionid);
2. 开辟数据存储空间。一般会在内存中创建相应的数据结构,但这种情况下,系统一旦掉电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库中,这样虽然会增加I/O开销,但session可以实现某种程度的持久化,而且更有利于session的共享;
3. 将session的全局唯一标示符发送给客户端。
问题的关键就在服务端如何发送这个session的唯一标识上。联系到HTTP协议,数据无非可以放到请求行、头域或Body里,基于此,一般来说会有两种常用的方式:cookie和URL重写。
1. Cookie
读者应该想到了,对,服务端只要设置Set-cookie头就可以将session的标识符传送到客户端,而客户端此后的每一次请求都会带上这个标识符,由于cookie可以设置失效时间,所以一般包含session信息的cookie会设置失效时间为0,即浏览器进程有效时间。至于浏览器怎么处理这个0,每个浏览器都有自己的方案,但差别都不会太大(一般体现在新建浏览器窗口的时候);
2. URL重写
所谓URL重写,顾名思义就是重写URL。试想,在返回用户请求的页面之前,将页面内所有的URL后面全部以get参数的方式加上session标识符(或者加在path info部分等等),这样用户在收到响应之后,无论点击哪个链接或提交表单,都会在再带上session的标识符,从而就实现了会话的保持。读者可能会觉得这种做法比较麻烦,确实是这样,但是,如果客户端禁用了cookie的话,URL重写将会是首选。
到这里,读者应该明白我前面为什么说session也算作是对HTTP的一种扩展了吧。如下两幅图是笔者在Firefox的Firebug插件中的截图,可以看到,当我第一次访问index.jsp时,响应头里包含了Set-cookie头,而请求头中没有。当我再次刷新页面时,图二显示在响应中不在有Set-cookie头,而在请求头中却有了Cookie头。注意一下Cookie的名字:jsessionid,顾名思义,就是session的标识符,另外可以看到两幅图中的jsessionid的值是相同的,原因笔者就不再多解释了。另外读者可能在一些网站上见过在最后附加了一段形如jsessionid=xxx的URL,这就是采用URL重写来实现的session。
(图一,首次请求index.jsp)
(图二,再次请求index.jsp)
Cookie和session由于实现手段不同,因此也各有优缺点和各自的应用场景:
1. 应用场景
Cookie的典型应用场景是Remember Me服务,即用户的账户信息通过cookie的形式保存在客户端,当用户再次请求匹配的URL的时候,账户信息会被传送到服务端,交由相应的程序完成自动登录等功能。当然也可以保存一些客户端信息,比如页面布局以及搜索历史等等。
Session的典型应用场景是用户登录某网站之后,将其登录信息放入session,在以后的每次请求中查询相应的登录信息以确保该用户合法。当然还是有购物车等等经典场景;
2. 安全性
cookie将信息保存在客户端,如果不进行加密的话,无疑会暴露一些隐私信息,安全性很差,一般情况下敏感信息是经过加密后存储在cookie中,但很容易就会被窃取。而session只会将信息存储在服务端,如果存储在文件或数据库中,也有被窃取的可能,只是可能性比cookie小了太多。
Session安全性方面比较突出的是存在会话劫持的问题,这是一种安全威胁,这在下文会进行更详细的说明。总体来讲,session的安全性要高于cookie;
3. 性能
Cookie存储在客户端,消耗的是客户端的I/O和内存,而session存储在服务端,消耗的是服务端的资源。但是session对服务器造成的压力比较集中,而cookie很好地分散了资源消耗,就这点来说,cookie是要优于session的;
4. 时效性
Cookie可以通过设置有效期使其较长时间内存在于客户端,而session一般只有比较短的有效期(用户主动销毁session或关闭浏览器后引发超时);
5. 其他
Cookie的处理在开发中没有session方便。而且cookie在客户端是有数量和大小的限制的,而session的大小却只以硬件为限制,能存储的数据无疑大了太多。

@ -0,0 +1,77 @@
# 文件说明
# node_modules
> 模块安装路径
# package.json
> 项目说明
# code
> 代码目录
## 0001express创建.js
> 搭建最初始的express
01.js
> 框架入门
02.js
> 中间件
03.js
> app.use
04.js
> 自定义404
05.js
> 错误处理中间件
06.js
> 模块化路由
07.js
> 模块化路由实现
router.js
> 模块化路由文件
08.js
> 获取get参数
09.js
> 获取post参数
10.js
> use方法
11.js
> 动态路由
12.js
> 静态文件
13.js
> 模板文件
14.js
> app.locals公共数据

@ -0,0 +1,63 @@
const Koa = require('koa'),
Router = require('koa-router'),
art = require('koa-art-template'),
path = require('path'),
static = require('koa-static'),
bodyParser = require('koa-bodyparser');
const routers = require('./routers/routers')
const app = new Koa();// 创建koa应用
const router = new Router(); // 创建路由,支持传递参数
art(app, {
root: path.join(__dirname, 'templates'),
extname: '.html',
debug: process.env.NODE_ENV !== 'production',
cache:false,
minimize: true
});// 将art模板导入到koa项目中
app.use(static(`${__dirname}/static`));// 设置静态文件读取目录,可以设置多个
app.use(bodyParser());// 设置使用bodyParser接受POST数据
app.use(async (ctx,next)=>{
await next();
// console.log(ctx.status);
if(parseInt(ctx.status)===404){
ctx.body=404;
}
// ctx.response.redirect('/about');//重定向
});// 定制404页面
router.use('/',routers.routes());
/*
router.get('/', async (ctx) => {
await ctx.render('input');
console.log(ctx.request)
// console.log(ctx.request.url);
// // console.log(ctx.request);
// console.log(ctx.request.query.name);// 获取get参数,获取不到是undefined
// console.log(ctx.request.querystring);// 将get参数转化为字符串格式
// console.log(ctx.params);// 获取动态路由
})
router.post("/123", async (ctx)=>{
ctx.body=ctx.request.body;
console.log(ctx.request.body)
})
*/
// 调用router.routes()来组装匹配好的路由,返回一个合并好的中间件
// 调用router.allowedMethods()获得一个中间件,当发送了不符合的请求时,会返回 `405 Method Not Allowed` 或 `501 Not Implemented`
app.use(router.routes());
app.use(router.allowedMethods({
// throw: true, // 抛出错误,代替设置响应头状态
// notImplemented: () => '不支持当前请求所需要的功能',
// methodNotAllowed: () => '不支持的请求方式'
}));
// 这俩要放在最后
app.listen(9999,()=>{
console.log("服务器已经启动:http://localhost:80")
})

@ -0,0 +1,40 @@
var app = require('koa')()
, logger = require('koa-logger')
, json = require('koa-json')
, views = require('koa-views')
, onerror = require('koa-onerror');
var index = require('./routes/index');
var users = require('./routes/users');
// error handler
onerror(app);
// global middlewares
app.use(views('views', {
root: __dirname + '/views',
default: 'jade'
}));
app.use(require('koa-bodyparser')());
app.use(json());
app.use(logger());
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
console.log('%s %s - %s', this.method, this.url, ms);
});
app.use(require('koa-static')(__dirname + '/public'));
// routes definition
app.use(index.routes(), index.allowedMethods());
app.use(users.routes(), users.allowedMethods());
// error-handling
app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
});
module.exports = app;

@ -0,0 +1,90 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('demo:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
// app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app.callback());
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

@ -0,0 +1,27 @@
{
"name": "demo",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "node bin/www",
"dev": "./node_modules/.bin/nodemon bin/www",
"prd": "pm2 start bin/www",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"co": "^4.6.0",
"debug": "^2.6.3",
"jade": "~1.11.0",
"koa": "^1.4.0",
"koa-bodyparser": "^2.5.0",
"koa-json": "^1.1.3",
"koa-logger": "^1.3.1",
"koa-onerror": "^1.3.1",
"koa-router": "^5.4.0",
"koa-static": "^1.5.2",
"koa-views": "^3.1.0"
},
"devDependencies": {
"nodemon": "^1.8.1"
}
}

@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}

@ -0,0 +1,15 @@
var router = require('koa-router')();
router.get('/', function *(next) {
yield this.render('index', {
title: 'Hello World Koa!'
});
});
router.get('/foo', function *(next) {
yield this.render('index', {
title: 'Hello World foo!'
});
});
module.exports = router;

@ -0,0 +1,13 @@
var router = require('koa-router')();
router.prefix('/users');
router.get('/', function *(next) {
this.body = 'this is a users response!';
});
router.get('/bar', function *(next) {
this.body = 'this is a users/bar response!';
});
module.exports = router;

@ -0,0 +1,6 @@
extends layout
block content
h1= message
h2= error.status
pre #{error.stack}

@ -0,0 +1,5 @@
extends layout
block content
h1= title
p Welcome to #{title}

@ -0,0 +1,7 @@
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content

@ -0,0 +1,78 @@
//开启严格模式
'use strict';
const os = require('os');
function deviceInfo() {
if (!os) {
return null;
}
const info = {
platform: '',
hostname: '',
cpu: '',
mac: ''
};
//操作系统平台
const pf = os.platform();
switch (pf) {
case 'darwin':
info.platform = 'macOS'
break;
case 'win32':
info.platform = 'Windows'
break;
default:
break;
}
//主机名
info.hostname = os.hostname();
//cpu
const cpus = os.cpus();
if (cpus.length) {
info.cpu = cpus[0].model;
}
//网卡
const netmap = os.networkInterfaces();
const conf = ['en0', 'WLAN', '以太网'];
// console.log(netmap);
for (let index = 0; index < conf.length; index++) {
const key = conf[index];
const item = netmap[key];
if (item) {
info.mac = item[0].mac
// console.log('mac:'+ mac);
break;
}
}
return info;
}
console.log(deviceInfo())
console.log(os.cpus())
console.log(os.arch())
console.log(os.endianness)
// console.log(os.getFreeMem())
console.log(os.getPriority())
console.log(os.loadavg())
console.log(os.networkInterfaces())
console.log(os.loadavg())
console.log(os.getOSRelease)
console.log(os.tmpdir())
console.log(os.getTotalMem)
console.log(os.getOSType)
console.log(os.getUptime)
console.log(os.getOSVersion)
console.log(os.constants)
//module.exports 暴露接口的方法
module.exports = {
deviceInfo: deviceInfo
};

@ -0,0 +1,22 @@
{
"name": "koa",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"art-template": "^4.13.2",
"koa": "^2.13.1",
"koa-art-template": "^1.1.1",
"koa-bodyparser": "^4.3.0",
"koa-router": "^10.1.1",
"koa-static": "^5.0.0",
"nodemon": "^2.0.12"
}
}

@ -0,0 +1,80 @@
# koa模板V0.1
## 安装的包
1. koa 核心包
2. art-templates
3. koa-art-templates 模版视图渲染中间件
## 使用方法
### 1 art
* options
```js
// 模板名
filename: null,
// 模板语法规则列表
rules: [nativeRule, artRule],
// 是否开启对模板输出语句自动编码功能。为 false 则关闭编码输出功能
// escape 可以防范 XSS 攻击
escape: true,
// 启动模板引擎调试模式。如果为 true: {cache:false, minimize:false, compileDebug:true}
debug: detectNode ? process.env.NODE_ENV !== 'production' : false,
// bail 如果为 true,编译错误与运行时错误都会抛出异常
bail: true,
// 是否开启缓存
cache: true,
// 是否开启压缩。它会运行 htmlMinifier,将页面 HTML、CSS、CSS 进行压缩输出
// 如果模板包含没有闭合的 HTML 标签,请不要打开 minimize,否则可能被 htmlMinifier 修复或过滤
minimize: true,
// 是否编译调试版
compileDebug: false,
// 模板路径转换器
resolveFilename: resolveFilename,
// 子模板编译适配器
include: include,
// HTML 压缩器。仅在 NodeJS 环境下有效
htmlMinifier: htmlMinifier,
// HTML 压缩器配置。参见 https://github.com/kangax/html-minifier
htmlMinifierOptions: {
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
// 运行时自动合并:rules.map(rule => rule.test)
ignoreCustomFragments: []
},
// 错误事件。仅在 bail 为 false 时生效
onerror: onerror,
// 模板文件加载器
loader: loader,
// 缓存中心适配器(依赖 filename 字段)
caches: caches,
// 模板根目录。如果 filename 字段不是本地路径,则在 root 查找模板
root: '/',
// 默认后缀名。如果没有后缀名,则会自动添加 extname
extname: '.art',
// 忽略的变量。被模板编译器忽略的模板变量列表
ignore: [],
// 导入的模板变量
imports: runtime
```

@ -0,0 +1,8 @@
const Router = require('koa-router');
let router = new Router();
router.get('/',async(ctx)=>{
ctx.body="首页";
})
module.exports=router;

@ -0,0 +1,11 @@
const Router = require('koa-router');
const router = new Router();
// 路由列表
const main = require('./main/get')
router.use('/',main.routes());
// router.use('/admin',admin.routes());
module.exports=router;

@ -0,0 +1,52 @@
/*css 初始化 */
html, body, ul, li, ol, dl, dd, dt, p, h1, h2, h3, h4, h5, h6,
form, fieldset, legend, img { margin:0; padding:0; }
fieldset, img,input,button { border:none; padding:0;margin:0;outline-style:none; }
ul, ol { list-style:none; }
input { padding-top:0; padding-bottom:0; font-family: "SimSun","宋体";}
select, input { vertical-align:middle; }
select, input, textarea { font-size:12px; margin:0; }
textarea { resize:none; }
img {border:0; vertical-align:middle;}
table { border-collapse:collapse; }
body {
font:12px/150% Arial,Verdana,"\5b8b\4f53";
color:#666;
background:#fff
}
.clearfix:before,.clearfix:after{
content:"";
display:table;
}
.clearfix:after{clear:both;}
.clearfix{
*zoom:1;/*IE/7/6*/
}
a{color:#666; text-decoration:none; }
a:hover{color:#C81623;}
h1,h2,h3,h4,h5,h6{text-decoration:none;font-weight:normal;}
s,i,em{font-style:normal;text-decoration:none;}
.col-red{color: #C81623!important;}
/*公共类*/
.w{
width: 1210px;margin:0 auto;
}
.fl {
float:left
}
.fr {
float:right
}
.al {
text-align:left
}
.ac {
text-align:center
}
.ar {
text-align:right
}
.hide {
display:none
}

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>post</title>
</head>
<body>
<form action="/123" method="post">
<input type="text" name="name">
<button type="submit">ok</button>
</form>
</body>
</html>

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>使用模板</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>

@ -0,0 +1,13 @@
var Koa = require('koa');
var bodyParser = require('koa-bodyparser');
var app = new Koa();
app.use(bodyParser());
app.use(async ctx => {
// the parsed body will store in ctx.request.body
// if nothing was parsed, body will be an empty object {}
ctx.body = ctx.request.body;
});
app.listen(80)

@ -0,0 +1,12 @@
{
"name": "learn-http",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

@ -0,0 +1,9 @@
const net = require("net");
const server = net.createServer()
server.connection(client=>{
console.log("E")
})
server.listen(80)

@ -0,0 +1,296 @@
# nodejs
> 尚硅谷 超哥
```js
console.log(arguments)//打印回调函数中的参数
```
进程和线程
进程
负责为程序运行提供必备的环境
相当于工厂中的车间
线程
计算机中的最小单位,负责执行进程中的任务
工厂中的工人
# nodejs简介
* 跨平台,运行于服务器的js运行环境
* V8引擎,事件驱动,非阻塞,异步IO模型
* 单线程,可用分布式拓展
* 开源
## 使用Node
```bash
node file.js
```
es-checker:查看es支持度,可以全局安装
## 一 基础
### 1.1 模块
缺陷:
* 没有模块系统
* 标准库较少
* 没有标准接口
* 缺乏管理系统
**node.js不能使用import**
nodejs的模块实在一个函数中,不是全局作用域
```js
//单个
//模块文件
//testModule.js
function a() {
// body...
}
module.exports=a;
//引入文件
//main.js
let testModule=require('./testModel');//可以不用加后缀,但是前面的./必须
testModule();
// 多个1
//模块文件
//testModule.js
var func1 = function() {
console.log("func1");
};
var func2 = function() {
console.log("func2");
};
exports.function1 = func1;
exports.function2 = func2;
//引入文件
//main.js
let testModule=require('./testModel');//可以不用加后缀,但是前面的./必须
testModule.function1();
testModule.function2();
// 多个2
//模块文件
//testModule.js
let a=function() {
console.log("a");
}
let b=function() {
console.log("b");
}
module.exports={
a,
b
}
let testModule=require('./testModel')
testModule.a();
testModule.b()
```
## 基本内置模块
### os模块
//模块都需要导入包
let os=require("os");
```js
let os=require('os');
hostname();//主机名
type();//系统名
platform();//编译时系统名
arch();//系统架构
release();//发行版本
uptime();//操作系统运行时间,单位为秒
loadavg();//返回一个1,5,15分钟平均负载的数组
totalmem();//返回系统总内存
freemem();//空闲内存
cpus();//数组,每个cpu信息
networkInterfaces();//获取网络接口列表
```
### url模块
```js
let url=require("url")
console.log("将url字符串转化为url对象");
url.parse();
console.log("将url对象转化为url字符串");
url.format(urlObj);
console.log("组合变数,构造url字符串");
url.resolve(fron,to);
```
### Query String模块
### util模块
全局对象
**global**
package
-package.json 描述文件(必须)
-bin 可执行二进制文件
-lib js文件
-doc 文档
-test 单元测试
不能写注释
npm命令
- npm -v 查看npm版本
- npm version 查看所有模块版本
- npm search 包名 搜索包
- npm install/i 包名 安装包
- npm remove/r 包名 删除包 或者uninstall
- npm install --save/-S 安装包并添加到依赖
- npm install 下载当前项目所有依赖
- npm install -g 安装到全局(一般都是工具)
-
- npm list 查看已经按照的包
初始化项目 npm init
npm国内镜像
npm i cnpm -g
导包本级找不到,会向上继续找,一直到根目录,如果找不到,报错
## Buffer(缓冲区)
-Buffer 的结构和数组很像,操作方式也很像
原生数组,性能比较差
原生数组存不了2进制文件
核心对象,不用导入
存储的是2进制,显示为16进制
```
let str= "Hello World!";
let buf = Buffer.form(str);
console.log(buf);//存储的是二进制
```
`let a = Buffer.alloc(x)`创建定长Buffer
`let b = Buffer.allocUnsafe(x)创建不初始化的空间的Buffer,但是含有敏感数据,但是效率高,因为省略了初始化控件的步骤`
buffer创建后大小不可更改,否则会出现内存错误,因为buffer在内存上操作
给buffer中元素操作,不能超过256,否则会溢出
.toString将Buffer转化为字符串
存到缓冲区`Buffer.from(str)`
### 文件系统fs
```js
const fs = require("fs");
```
同步文件操作和一部文件操作
同步会阻塞程序运行,必须等待文件行为完成
异步是等操作完成时通过回调函数返回内容
* 文件写入(同步) 出现一场会完蛋
```js
//打开文件
fs.openSync(path,flags[,mode])
- path文件路径
- flags操作类型
r只读
w写入
-mode(可选),设置文件操作权限,一般不写
//该方法会返回一个文件对象(文件描述符)
//let fd =fs.openSync("hellow.txt","w")
//写入文件
fs.writeSync(fd(文件描述符),string[,position(写入起始位置)[,encoding]])
position起始位置
encoding写入编码,默认utf-8
//fs.writeSync(fd,"Hello World!");
//保存关闭文件
fs.closeSync(fd);
```
* 文件写入(异步)
```js
//打开文件
fs.open(path[, flags[, mode]], callback),结果是回调函数
path <string> | <Buffer> | <URL>
flags <string> | <number> 请参阅对文件系统 flags 的支持。 默认值: 'r'。
mode <string> | <integer> 默认值: 0o666 (可读可写)
callback <Function>
err <Error>
fd <integer>
//fs.open("filename","w",(err,fd)=>{})
//写入文件
fs.write(fd, buffer[, offset[, length[, position]]], callback)//在回调函数中执行
//关闭文件
fs.close(fd[, callback])
```
* 简单文件写入
```
fs.writeFile(fs.writeFile(file, data[, options], callback))
fs.writeFileSync(file, data[, options])
```
* 流文件写入(更好印度贵大文件和性能解决方案)
```js
let fd = fs.createWriteStream(path[,option])
fd.once("open",()=>{console.log("监听打开事件,因为只会生效一次,所以")})
fd.wirte(Str)
fd.close()//不能使用这个,否则会瞬间关闭,后面的写入会失效
fd.end();//这个可以正常关闭
```
* 读取性质的参考api

@ -0,0 +1,18 @@
const express = require("express");
// const gfs = require("gfs")
const app = express();
app.get("/download",(req,res)=>{
gfs.getGridFile('./atom-macs.zip', function(err, file){
res.header('Content-Type', file.contentType);
res.header('Content-Disposition', 'attachment; filename='+file.filename);
return file.stream(true).pipe(res);
});
})
app.set('port', 80);
app.set('host','192.168.31.74');
app.listen("80")

@ -0,0 +1,14 @@
const express = require("express");
const app = express();
app.get("/download",(req,res)=>{
// console.log(res)res
res.download('./atom-macs.zip')//下载命令 另一种可以通过使用iframe的src来操作,后面还可以修改文件名称
// res.send("xs")
})
app.set('port', 80);
app.set('host','192.168.31.74');
app.listen("80")

@ -0,0 +1,855 @@
{
"name": "webDownload",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"express": "^4.17.1"
}
},
"node_modules/accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
"dependencies": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"node_modules/body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
"dependencies": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
"dependencies": {
"safe-buffer": "5.1.2"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
"dependencies": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
"body-parser": "1.19.0",
"content-disposition": "0.5.3",
"content-type": "~1.0.4",
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "~1.1.2",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.5",
"qs": "6.7.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.1.2",
"send": "0.17.1",
"serve-static": "1.14.1",
"setprototypeof": "1.1.1",
"statuses": "~1.5.0",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"engines": {
"node": ">= 0.10.0"
}
},
"node_modules/finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/http-errors": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
"dependencies": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/mime-db": {
"version": "1.49.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz",
"integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.32",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz",
"integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==",
"dependencies": {
"mime-db": "1.49.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"node_modules/negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
"engines": {
"node": ">=0.6"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/raw-body": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
"dependencies": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/send": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
"dependencies": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.7.2",
"mime": "1.6.0",
"ms": "2.1.1",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/send/node_modules/ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
},
"node_modules/serve-static": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
"dependencies": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.17.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"node_modules/statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
"engines": {
"node": ">=0.6"
}
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
"engines": {
"node": ">= 0.8"
}
}
},
"dependencies": {
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
"requires": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
}
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
"requires": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
}
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
},
"content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
"requires": {
"safe-buffer": "5.1.2"
}
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
"requires": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
"body-parser": "1.19.0",
"content-disposition": "0.5.3",
"content-type": "~1.0.4",
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "~1.1.2",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.5",
"qs": "6.7.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.1.2",
"send": "0.17.1",
"serve-static": "1.14.1",
"setprototypeof": "1.1.1",
"statuses": "~1.5.0",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
}
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
}
},
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"http-errors": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.49.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz",
"integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA=="
},
"mime-types": {
"version": "2.1.32",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz",
"integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==",
"requires": {
"mime-db": "1.49.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"requires": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"send": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.7.2",
"mime": "1.6.0",
"ms": "2.1.1",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
}
}
},
"serve-static": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.17.1"
}
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
}
}
}

@ -0,0 +1,448 @@
# JavaScript
## 运算符、数据类型和流程循环语句
switch case 采用的是===
default 没有选中的case
## String
字符串补全:str.padStart(length,"x")
Str.padEnd(length,"x")
## 函数与对象
### (1) 函数的声明
* 驼峰命名法
大驼峰:首字母大写
小驼峰:首字母小写
```js
function funName(参数){
}
```
当一个函数声明多次,后面的会覆盖
函数名的提升:所有的函数都会被提升带代码头部
不能再条件语句中声明函数
### (2)函数的属性和方法
内部属性
```js
function getName(){};
getName.name//这里会显示函数的名字
```
当这样子声明时,不能直接通过函数名调用
``` 
let a = function as(){}
a();//正确
as();//报错
```
### (3) 函数的作用域
全局作用域
局部作用域
### (4) 函数的参数
函数的参数可以省略,也可以多,缺少的undefined
查看函数有几个参数fun.length
数值,字符串,布尔值不会再函数中改变,这个原始类型,引用类型才会改变
读取参数
arguments,只有在函数内部才能出现
### (5) 其他
自调用
```js
(function a(){console.log("xsxsxsxs")}())
(function a(){console.log("xsxsxsxs")}()
```
Eval()将字符串当作语句执行
```js
eval(console.log("Hello World!"));//Hello World!
```
### (6) 闭包
函数嵌套,内部函数调用外部参数
函数变量一直在内存当中(一般函数执行完,变量会被回收,有必报的话,变量会一直存在于内存中)
### (7) 对象
```js
let a={
q:"sx",
"xsx":"xs"
}
a.q;
a["xsx"];//不能使用a."xsx";
Object.keys(a);//返回key数组
delete obj.p // true删除对象属性
```
## 标准库 Math和Date
### (1)Math
Math是 JavaScript 的**原生对象**,提供各种数学功能。**该对象不是构造函数**,不能生成实例,所有的属性和方法都必须在Math对象上调用。
#### 静态属性
Math对象的静态属性,提供以下一些数学常数。
> Math.E:常数e。
> Math.LN2:2 的自然对数。
> Math.LN10:10 的自然对数。
> Math.LOG2E:以 2 为底的e的对数。
> Math.LOG10E:以 10 为底的e的对数。
> Math.PI:常数 Pi。
> Math.SQRT1_2:0.5 的平方根。
> Math.SQRT2:2 的平方根。
```js
Math.E // 2.718281828459045
Math.LN2 // 0.6931471805599453
Math.LN10 // 2.302585092994046
Math.LOG2E // 1.4426950408889634
Math.LOG10E // 0.4342944819032518
Math.PI // 3.141592653589793
Math.SQRT1_2 // 0.7071067811865476
Math.SQRT2 // 1.4142135623730951
```
这些属性都是只读的,不能修改。
#### 静态方法
Math对象提供以下一些静态方法。
> Math.abs():绝对值
> Math.ceil():向上取整
> Math.floor():向下取整
> Math.max():最大值
> Math.min():最小值 Math.max方法返回参数之中最大的那个值,Math.min返回最小的那个值。如果参数为空, Math.min返回Infinity, Math.max返回-Infinity。
> Math.pow():指数运算 Math.pow方法返回以第一个参数为底数、第二个参数为幂的指数值。
> Math.sqrt():平方根
> Math.log():自然对数
> Math.exp():e的指数
> Math.round():四舍五入
> Math.random():随机数 返回0到1之间的一个伪随机数,可能等于0,但是一定小于1。
#### 三角函数方法
Math对象还提供一系列三角函数方法。
> Math.sin():返回参数的正弦(参数为弧度值)
> Math.cos():返回参数的余弦(参数为弧度值)
> Math.tan():返回参数的正切(参数为弧度值)
> Math.asin():返回参数的反正弦(返回值为弧度值)
> Math.acos():返回参数的反余弦(返回值为弧度值)
> Math.atan():返回参数的反正切(返回值为弧度值)
### (2) Date
#### 普通函数的用法
Date对象可以作为普通函数直接调用,返回一个代表当前时间的字符串。
```js
Date()
// "Tue Dec 01 2015 09:34:43 GMT+0800 (CST)"
```
注意,即使带有参数,Date作为普通函数使用时,返回的还是当前时间。
```js
Date(2000, 1, 1)
// "Tue Dec 01 2015 09:34:43 GMT+0800 (CST)"
```
上面代码说明,无论有没有参数,直接调用Date总是返回当前时间。
#### 构造函数的用法
Date还可以当作构造函数使用。对它使用new命令,会返回一个Date对象的实例。如果不加参数,实例代表的就是当前时间。
```js
var today = new Date();
```
Date实例有一个独特的地方。其他对象求值的时候,都是默认调用.valueOf()方法,但是Date实例求值的时候,默认调用的是toString()方法。这导致对Date实例求值,返回的是一个字符串,代表该实例对应的时间。
```js
var today = new Date();
today
// "Tue Dec 01 2015 09:34:43 GMT+0800 (CST)"
// 等同于
today.toString()
// "Tue Dec 01 2015 09:34:43 GMT+0800 (CST)"
```
作为构造函数时,Date对象可以接受多种格式的参数,返回一个该参数对应的时间实例。
```js
// 参数为时间零点开始计算的毫秒数
new Date(1378218728000)
// Tue Sep 03 2013 22:32:08 GMT+0800 (CST)
// 参数为日期字符串
new Date('January 6, 2013');
// Sun Jan 06 2013 00:00:00 GMT+0800 (CST)
// 参数为多个整数,
// 代表年、月、日、小时、分钟、秒、毫秒
new Date(2013, 0, 1, 0, 0, 0, 0)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
```
关于Date构造函数的参数,有几点说明。
第一点,参数可以是负整数,代表1970年元旦之前的时间。
```js
new Date(-1378218728000)
// Fri Apr 30 1926 17:27:52 GMT+0800 (CST)
```
第二点,只要是能被Date.parse()方法解析的字符串,都可以当作参数。
```js
new Date('2013-2-15')
new Date('2013/2/15')
new Date('02/15/2013')
new Date('2013-FEB-15')
new Date('FEB, 15, 2013')
new Date('FEB 15, 2013')
new Date('Feberuary, 15, 2013')
new Date('Feberuary 15, 2013')
new Date('15 Feb 2013')
new Date('15, Feberuary, 2013')
// Fri Feb 15 2013 00:00:00 GMT+0800 (CST)
```
上面多种日期字符串的写法,返回的都是同一个时间。
第三,参数为年、月、日等多个整数时,年和月是不能省略的,其他参数都可以省略的。也就是说,这时至少需要两个参数,因为如果只使用“年”这一个参数,Date会将其解释为毫秒数。
```js
new Date(2013)
// Thu Jan 01 1970 08:00:02 GMT+0800 (CST)
```
上面代码中,2013被解释为毫秒数,而不是年份。
```js
new Date(2013, 0)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
new Date(2013, 0, 1)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
new Date(2013, 0, 1, 0)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
new Date(2013, 0, 1, 0, 0, 0, 0)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
```
上面代码中,不管有几个参数,返回的都是2013年1月1日零点。
最后,各个参数的取值范围如下。
> 年:使用四位数年份,比如2000。如果写成两位数或个位数,则加上1900,即10代表1910年。如果是负数,表示公元前。
> 月:0表示一月,依次类推,11表示12月。
> 日:1到31。
> 小时:0到23。
> 分钟:0到59。
> 秒:0到59
> 毫秒:0到999。
注意,月份从0开始计算,但是,天数从1开始计算。另外,除了日期的默认值为1,小时、分钟、秒钟和毫秒的默认值都是0。
这些参数如果超出了正常范围,会被自动折算。比如,如果月设为15,就折算为下一年的4月。
```js
new Date(2013, 15)
// Tue Apr 01 2014 00:00:00 GMT+0800 (CST)
new Date(2013, 0, 0)
// Mon Dec 31 2012 00:00:00 GMT+0800 (CST)
```
上面代码的第二个例子,日期设为0,就代表上个月的最后一天。
参数还可以使用负数,表示扣去的时间。
```js
new Date(2013, -1)
// Sat Dec 01 2012 00:00:00 GMT+0800 (CST)
new Date(2013, 0, -1)
// Sun Dec 30 2012 00:00:00 GMT+0800 (CST)
```
#### 日期的运算
类型自动转换时,Date实例如果转为数值,则等于对应的毫秒数;如果转为字符串,则等于对应的日期字符串。所以,两个日期实例对象进行减法运算时,返回的是它们间隔的毫秒数;进行加法运算时,返回的是两个字符串连接而成的新字符串。
```js
var d1 = new Date(2000, 2, 1);
var d2 = new Date(2000, 3, 1);
d2 - d1
// 2678400000
d2 + d1
// "Sat Apr 01 2000 00:00:00 GMT+0800 (CST)Wed Mar 01 2000 00:00:00 GMT+0800 (CST)"
```
#### 静态方法
##### Date.now()
Date.now方法返回当前时间距离时间零点(1970年1月1日 00:00:00 UTC)的毫秒数,相当于 Unix 时间戳乘以1000。
```js
Date.now() // 1364026285194
```
##### Date.parse()
Date.parse方法用来解析日期字符串,返回该时间距离时间零点(1970年1月1日 00:00:00)的毫秒数。
日期字符串应该符合 RFC 2822 和 ISO 8061 这两个标准,即YYYY-MM-DDTHH:mm:ss.sssZ格式,其中最后的Z表示时区。但是,其他格式也可以被解析,请看下面的例子。
```js
Date.parse('Aug 9, 1995')
Date.parse('January 26, 2011 13:51:50')
Date.parse('Mon, 25 Dec 1995 13:30:00 GMT')
Date.parse('Mon, 25 Dec 1995 13:30:00 +0430')
Date.parse('2011-10-10')
Date.parse('2011-10-10T14:48:00')
```
上面的日期字符串都可以解析。
如果解析失败,返回NaN。
```js
Date.parse('xxx') // NaN
```
#### 实例方法
Date的实例对象,有几十个自己的方法,除了valueOf和toString,可以分为以下三类。
> to类:从Date对象返回一个字符串,表示指定的时间。
> get类:获取Date对象的日期和时间。
> set类:设置Date对象的日期和时间。
##### Date.prototype.valueOf()
valueOf方法返回实例对象距离时间零点(1970年1月1日00:00:00 UTC)对应的毫秒数,该方法等同于getTime方法。
```js
var d = new Date();
d.valueOf() // 1362790014817
d.getTime() // 1362790014817
```
预期为数值的场合,Date实例会自动调用该方法,所以可以用下面的方法计算时间的间隔。
```js
var start = new Date();
// ...
var end = new Date();
var elapsed = end - start;
```
##### get 类方法
Date对象提供了一系列get*方法,用来获取实例对象某个方面的值。
> getTime():返回实例距离1970年1月1日00:00:00的毫秒数,等同于valueOf方法。
> getDate():返回实例对象对应每个月的几号(从1开始)。
> getDay():返回星期几,星期日为0,星期一为1,以此类推。
> getYear():返回距离1900的年数。
> getFullYear():返回四位的年份。
> getMonth():返回月份(0表示1月,11表示12月)。
> getHours():返回小时(0-23)。
> getMilliseconds():返回毫秒(0-999)。
> getMinutes():返回分钟(0-59)。
> getSeconds():返回秒(0-59)。
> getTimezoneOffset():返回当前时间与 UTC 的时区差异,以分钟表示,返回结果考虑到了夏令时因素。
所有这些get*方法返回的都是整数,不同方法返回值的范围不一样。
> 分钟和秒:0 到 59 小时:0 到 23 星期:0(星期天)到 6(星期六) 日期:1 到 31 月份:0(一月)到 11(十二月) 年份:距离1900年的年数
```js
var d = new Date('January 6, 2013');
d.getDate() // 6
d.getMonth() // 0
d.getYear() // 113
d.getFullYear() // 2013
```
下面是一个例子,计算本年度还剩下多少天。
```js
function leftDays() {
var today = new Date();
var endYear = new Date(today.getFullYear(), 11, 31, 23, 59, 59, 999);
var msPerDay = 24 * 60 * 60 * 1000;
return Math.round((endYear.getTime() - today.getTime()) / msPerDay);
}
```
##### set 类方法
Date对象提供了一系列set*方法,用来设置实例对象的各个方面。
> setDate(date):设置实例对象对应的每个月的几号(1-31),返回改变后毫秒时间戳。
> setYear(year): 设置距离1900年的年数。
> setFullYear(year [, month, date]):设置四位年份。
> setHours(hour [, min, sec, ms]):设置小时(0-23)。
> setMilliseconds():设置毫秒(0-999)。
> setMinutes(min [, sec, ms]):设置分钟(0-59)。
> setMonth(month [, date]):设置月份(0-11)。
> setSeconds(sec [, ms]):设置秒(0-59)。
> setTime(milliseconds):设置毫秒时间戳。
这些方法基本是跟get*方法一一对应的,但是没有setDay方法,因为星期几是计算出来的,而不是设置的。另外,需要注意的是,凡是涉及到设置月份,都是从0开始算的,即0是1月,11是12月。
## DOM

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

@ -0,0 +1,9 @@
console.log("start")
for(let i = 0;i<10;i++){
console.log(i)
}
console.log("结束",end=" ")
// for是同步的

@ -0,0 +1,13 @@
let i = 0;
let s = setInterval(function (){
if(i==100){
console.log("轮询结束")
clearInterval(s);
}
console.log(i)
i++
// if(i%5==0){
// }
},5)

@ -0,0 +1,11 @@
let i=120;
function s(sn){
if(sn==0){
return 1
}else{
return sn*s(sn-1)
}
}
console.log(s(i))

@ -0,0 +1,19 @@
// 让函数中声明的变量常驻内存
function fun(){
let i=99;
add=function () {
i+=1;
}
return ()=>{console.log(i)}
}
let sss=fun()
sss()
add()
sss()
console.log((sss.length))

@ -0,0 +1,714 @@
## 基础数据类型
Number, String, Undefined, Null, Boolean
- 数字支持进制
0b - 二进制
0o - 八进制
0x - 十六进制
- Undefined和Null
这两个值可以赋予任何类型
## 引用数据类型
### 数组
```ts
let arr: Number[] = [1, 2, 3];
let arr2: [] = [];// 空数组,不能再存值
// 泛型
let arr3: Array<Number> = [10, 20, 99]
```
### 对象
```ts
let obj: Object = {};// 除了Number,String,Boolean
obj = null;
obj = undefined;
obj = [];
obj = new String();
obj = String
```
## Any 任意类型
- 用于不明确传递的值,如后台返回的数据
```ts
let a: Any = null;
a = 32;
a = [1, 2, 3];
a = 'Hello'
let newArr: any[] = [1, 'a', true]
```
## Void 空值
- 没有任何返回值的函数
```ts
function fun() :Void{
return undefined;// Undefined也算是空值
}
```
## 类型推断
- 没有明确制定类型时做的一个推断
```ts
let a = 32;
a = true;// 这里会报错,上面a已经被定义为了Number类型
let b; // 没有赋值
b = 32;
b = true;
// b为Any类型
```
## 联合类型
```ts
let a: Boolean | Number | String = true;// 后面还可以再跟多种类型
/*
** 只能访问这些类型的共有方法
*/
a.split('');// 会报错
a.otString();// 不会报错
a = 123; // 这里不会报错
a = false;// 不会报错
a = '32';// 不报错
a.split('');// 这里因为赋值了所以不会报错
```
## 接口——对象类型
- 对对象的约束,描述对象的形状
- 定义接口名称开头使用大写的`I`
- 非可选属性不能多也不能少
```ts
interface Iperson = {
name: String;// 分号和逗号都可以
age: Number;
}
let xiaoming = {
name: '小明',
age: 18
}
```
### 可选属性
```ts
interface IPerson{
name: String;
age: Number;
sex?: String;// sex可以没有
// 不能有其他的属性
}
```
### 任意属性(不确定时)
- 一但定义了任意类型,该对象内部必须所有的属性(包括已确定的属性)都为该任意类型的类型子集
- 一个接口只能定义一个任意属性,如果有多个类型,任意属性可以使用联合类型`[propName: String]: String | Number | Boolean`
```ts
interface IPerson{
[propName: String]: String
}
let xi: IPerson{
name: "何琋",
age: "32"
}
```
```ts
interface IPerson{
age: Number;
[propName: String]: String;// 这里会让上面报错,Number类型不是String类型的子集,所以一般使用Any类型
}
```
### 只读属性
```ts
interface IPerson{
readonly sex: String;
}
let hexi: IPerson = {
sex : "男"
}
hexi.sex = "女";// 这里会报错,sex为只读属性
```
```ts
// 测试只读任意属性
interface IPerson{
readonly [propName: string]: string
}
let hexi:IPerson = {
name: "何琋",
sex: "男"
}
hexi.sex = "女"
```
## 接口——数组类型
- 不常用
```ts
interface IArray{
[index:Number]: Number;// index: Number 下标是数字的
}
```
## 接口——函数类型
```ts
interface ISearchFunc{
(a: String, b: String): boolean;
}
const fun1:ISearchFunc = function(a: String, b: String): boolean{
return a.search(b) !== -1
}
```
## 函数
### 函数声明
```js
// 函数声明,命名函数
function fun1(a, b){
return a + b
}
// 函数表达式,匿名函数
const fun2 = function(a, b){
return a + b
}
```
```ts
function fun1(a: Number, b: Number): Number{
return a + b
}
const fun2 = function(a: Number, b:Number): Number{
return a + b
}
const fun3: (a: Number, b:Number) => Number = function(a: Number, b:Number): Number{
return a + b
}
```
### 可选参数和默认参数
- 必选参数不能位于可选参数之后
- 默认参数可以放在可选参数之后
```ts
const getName = function(x: String = "何", y?: String): String{
return x = y;
}
const geName2 = function(x: String, y?: String, z: String = "早上好"): String{
return x + y + z
}
```
### 剩余参数
```ts
const fn = function(a: String, b: String, args: number[]){
console.log(a, b, args)
}
```
### 函数重载
- 函数名称相同,参数类型不同
```ts
// 函数重载
// 这里需要先定义
function add(x: string, y:string): string
function add(x: number, y: number): number
function add(x: string | number, y: string | number): string | number{
if(typeof x === 'string' && typeof y === "string"){
return x + y
}else if(typeof x === 'number' && typeof y === 'number'){
return x + y
}
}
console.log(add(1, 2))// 3
console.log(add('何', '琋'))// 何琋
```
## 断言
- 联合类型断言为其中一个类型
`变量 as 类型`
`<类型>变量`
```ts
// 断言
function getSome(x: number | string): void{
if((x as string).length){
console.log((<string>x).length)
}else{
console.log(x.toString().length)
}
}
getSome(32389382)
getSome('何琋大坏蛋')
```
- 将任何一个变量断言为any,any可以访问任意属性
```ts
(window as any).a = '何琋'// 不进行断言是无法访问的
```
- 将any类型断言为任意具体子类型
## 类型别名
```ts
type name = string
let a: name = "何琋"
```
- 字面量类型
```ts
// 类型别名何字面量类型
type newName = "何琋" | "何蔺" | "何茗"
let myName: newName = "何琋"
console.log(myName)
```
## 元组
```ts
let arr: number[] = [1, 2, 3, 4]
// 数组合并同一类型
// 元组Tuple,合并不同类型
let Tarr: [number, string] = [1, '1'] // 这里不能再添加,也不能换位
// 添加元素时,需要从生命中的类型取
Tarr.push('32')
Tarr.push(32)
Tarr.push(true)// 报错
```
## 枚举
- Enum
```ts
// 自动赋值
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
// 事实上被编译为
var Days;
(function (Days) {
Days[Days["Sun"] = 0] = "Sun";
Days[Days["Mon"] = 1] = "Mon";
Days[Days["Tue"] = 2] = "Tue";
Days[Days["Wed"] = 3] = "Wed";
Days[Days["Thu"] = 4] = "Thu";
Days[Days["Fri"] = 5] = "Fri";
Days[Days["Sat"] = 6] = "Sat";
})(Days || (Days = {}));
// 手动赋值
enum test {
one=1,
two=2,
three=3,
four=4
}
// 半自动
enum test2{
one=1,
tow,// 2
three=12,
four,// 13
}
```
- 常数项和计算所得项
```ts
enum Color {Red = "red".length, Green, Blue};// 会报错,计算所得项后面不能跟自动赋值
```
- 常数枚举
- 常数枚举不会被编译,哪里用那里直接赋值
- 常数枚举不能使用计算所得项
```ts
const enum test{
one,
two,
three
}
```
- 外部枚举
```ts
declare enum test{
Up,
Down,
Left,
Right
}
// 可以和const一起使用
declare const enum test2{
Up,
Down,
Left,
Right
}
```
## 类
- 抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现
- 封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
- 继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
- 多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。比如 `Cat`  `Dog` 都继承自 `Animal`,但是分别实现了自己的 `eat` 方法。此时针对某一个实例,我们无需了解它是 `Cat` 还是 `Dog`,就可以直接调用 `eat` 方法,程序会自动判断出来应该如何执行 `eat`
```js
// 属性和方法
class Animal {
public name;
constructor(name) {
this.name = name;
}
sayHi() {
return `My name is ${this.name}`;
}
}
let a = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack
// 类的继承
class Cat extends Animal {
constructor(name) {
super(name); // 调用父类的 constructor(name)
console.log(this.name);
}
sayHi() {
return 'Meow, ' + super.sayHi(); // 调用父类的 sayHi()
}
}
let c = new Cat('Tom'); // Tom
console.log(c.sayHi()); // Meow, My name is Tom
```
- 存取器
```js
class Animal {
constructor(name) {
this.name = name;
}
get name() {
return 'Jack';
}
set name(value) {
console.log('setter: ' + value);
}
}
let a = new Animal('Kitty'); // setter: Kitty
a.name = 'Tom'; // setter: Tom
console.log(a.name); // Jack
```
- 静态方法和属性
```js
class Animal {
static name = 42;
static isAnimal(a) {
return a instanceof Animal;
}
}
let a = new Animal('Jack');
Animal.isAnimal(a); // true
a.isAnimal(a); // TypeError: a.isAnimal is not a function
```
### TypeScript 中类的用法
- `public` 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 `public` 
- `private` 修饰的属性或方法是私有的,不能在声明它的类的外部访问
- `protected` 修饰的属性或方法是受保护的,它和 `private` 类似,区别是它在子类中也是允许被访问的
```ts
class Animal {
public name;
public constructor(name) {
this.name = name;
}
}
let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom
```
```ts
class Animal {
private name;
public constructor(name) {
this.name = name;
}
}
let a = new Animal('Jack');
console.log(a.name);
a.name = 'Tom';
// index.ts(9,13): error TS2341: Property 'name' is private and only accessible within class 'Animal'.
// index.ts(10,1): error TS2341: Property 'name' is private and only accessible within class 'Animal'.
```
```ts
class Animal {
protected name;
public constructor(name) {
this.name = name;
}
}
class Cat extends Animal {
constructor(name) {
super(name);
console.log(this.name);
}
}
```
当构造函数修饰为 `private` 时,该类不允许被继承或者实例化
```ts
class Animal {
public name;
private constructor(name) {
this.name = name;
}
}
class Cat extends Animal {
constructor(name) {
super(name);
}
}
let a = new Animal('Jack');
// index.ts(7,19): TS2675: Cannot extend a class 'Animal'. Class constructor is marked as private.
// index.ts(13,9): TS2673: Constructor of class 'Animal' is private and only accessible within the class declaration.
```
当构造函数修饰为 `protected` 时,该类只允许被继承:
```ts
class Animal {
public name;
protected constructor(name) {
this.name = name;
}
}
class Cat extends Animal {
constructor(name) {
super(name);
}
}
let a = new Animal('Jack');
// index.ts(13,9): TS2674: Constructor of class 'Animal' is protected and only accessible within the class declaration.
```
### readonly
只读属性关键字,只允许出现在属性声明或索引签名或构造函数中。
```ts
class Animal {
readonly name;
public constructor(name) {
this.name = name;
}
}
let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
// index.ts(10,3): TS2540: Cannot assign to 'name' because it is a read-only property.
```
注意如果 `readonly` 和其他访问修饰符同时存在的话,需要写在其后面。
```ts
class Animal {
// public readonly name;
public constructor(public readonly name) {
// this.name = name;
}
}
```
### 抽象类
`abstract` 用于定义抽象类和其中的抽象方法。
首先,抽象类是不允许被实例化的:
其次,抽象类中的抽象方法必须被子类实现:
```ts
abstract class Animal {
public name;
public constructor(name) {
this.name = name;
}
public abstract sayHi();
}
class Cat extends Animal {
public sayHi() {
console.log(`Meow, My name is ${this.name}`);
}
}
let cat = new Cat('Tom');
```
- 类的类型
给类加上 TypeScript 的类型很简单,与接口类似:
```ts
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sayHi(): string {
return `My name is ${this.name}`;
}
}
let a: Animal = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack
```
## 类与接口
```ts
interface Alarm {
alert(): void;
}
```
## 泛型
```ts
unction createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray<string>(3, 'x'); // ['x', 'x', 'x']
```
- 多参数
```ts
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}
swap([7, 'seven']); // ['seven', 7]
```
- 泛型约束
```ts
interface Lengthwise {
length: number;
}
// 只允许这个函数传入那些包含 `length` 属性的变量
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
```
- 泛型接口
```ts
interface CreateArrayFunc<T> {
(length: number, value: T): Array<T>;
}
let createArray: CreateArrayFunc<any>;
createArray = function<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray(3, 'x'); // ['x', 'x', 'x']
```
- 泛型类
```ts
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
```

@ -0,0 +1,6 @@
// 测试只读任意属性
var hexi = {
name: "何琋",
sex: "男"
};
hexi.sex = "女";

@ -0,0 +1,12 @@
// 测试只读任意属性
interface IPerson{
readonly [propName: string]: string
}
let hexi:IPerson = {
name: "何琋",
sex: "男"
}
// hexi.sex = "女"

@ -0,0 +1,11 @@
// 函数重载
function add(x, y) {
if (typeof x === 'string' && typeof y === "string") {
return x + y;
}
else if (typeof x === 'number' && typeof y === 'number') {
return x + y;
}
}
console.log(add(1, 2)); // 3
console.log(add('何', '琋')); // 何琋

@ -0,0 +1,15 @@
// 函数重载
function add(x: string, y:string): string
function add(x: number, y: number): number
function add(x: string | number, y: string | number): string | number{
if(typeof x === 'string' && typeof y === "string"){
return x + y
}else if(typeof x === 'number' && typeof y === 'number'){
return x + y
}
}
console.log(add(1, 2))// 3
console.log(add('何', '琋'))// 何琋

@ -0,0 +1,17 @@
// 断言
function getSome(x) {
if (x.length) {
console.log(x.length);
}
else {
console.log(x.toString().length);
}
}
getSome(32389382);
getSome('何琋大坏蛋');
function fn(x, y) {
return x + y;
}
var a = fn(1, 2);
var b = fn('何', '琋');
console.log(a, b);

@ -0,0 +1,21 @@
// 断言
function getSome(x: number | string): void{
if((x as string).length){
console.log((<string>x).length)
}else{
console.log(x.toString().length)
}
}
getSome(32389382)
getSome('何琋大坏蛋')
function fn(x: any, y:any): any{
return x + y
}
let aas: number = fn(1, 2) as number;
let ba: string = fn('何', '琋') as string
console.log(aas, ba)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save