├── koa2
├── context.md
├── compose.js
└── application.md
├── test-cross
├── serverProxy
│ ├── index.html
│ └── server.js
├── cors
│ ├── server.js
│ └── index.html
├── postMessage
│ ├── server
│ │ └── data.html
│ └── client
│ │ └── index.html
├── jsonp
│ ├── server.js
│ └── index.html
└── package.json
├── .gitignore
├── test-webpack
├── src
│ ├── b.css
│ ├── a.css
│ ├── a.less
│ ├── b.less
│ ├── common.js
│ ├── common.css
│ ├── a.js
│ └── b.js
├── dist
│ ├── pageA-35be2c21107ce4016c324daaa1dd5e28.css
│ ├── pageA-d7ac82de795ddf50c9df43291d77b4c8.css
│ ├── pageB-56185455ea60f01155a65497e9bf6c85.css
│ ├── index.html
│ ├── pageA-8ddb2f0f51a8139475bb.js
│ ├── pageA-b5b4e2893bce99fd5c57.js
│ ├── pageB-34be879b3374ac9b2072.js
│ ├── bundle.js
│ ├── runtime-12168eb5ce29428d6ad5.js
│ └── runtime-1b40e842c0decf252041.js
├── package.json
└── webpack.config.js
├── vue.md
├── webpack.md
├── README.md
├── test-html&css
├── 3.html
├── 4.html
├── 5.html
├── 1.html
├── 2.html
└── 6.html
├── async.md
├── careful.md
├── test-javascript
├── 4.js
├── 2.js
├── 1.js
└── 3.js
├── xss&csrf.md
├── brower.md
├── test-drag
└── index.html
├── javascript.md
├── http.md
├── prototype.md
├── html&css.md
└── observer.md
/koa2/context.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test-cross/serverProxy/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .history
2 | .vscode
3 | node_modules
4 | yarn-error.log
--------------------------------------------------------------------------------
/test-webpack/src/b.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: yellow;
3 | }
4 |
--------------------------------------------------------------------------------
/test-webpack/src/a.css:
--------------------------------------------------------------------------------
1 | p {
2 | width: 100px;
3 | height: 200px;
4 | }
5 |
--------------------------------------------------------------------------------
/test-webpack/src/a.less:
--------------------------------------------------------------------------------
1 | @import url('./a.css');
2 | div {
3 | width: 200px;
4 | }
5 |
--------------------------------------------------------------------------------
/test-webpack/dist/pageA-35be2c21107ce4016c324daaa1dd5e28.css:
--------------------------------------------------------------------------------
1 | *{padding:0;margin:0}body{width:100%;height:200%}
--------------------------------------------------------------------------------
/test-webpack/src/b.less:
--------------------------------------------------------------------------------
1 | @import url('./b.css');
2 | span {
3 | display: inline-block;
4 | width: 100px;
5 | }
6 |
--------------------------------------------------------------------------------
/test-webpack/src/common.js:
--------------------------------------------------------------------------------
1 | require('./common.css')
2 | module.export = function sum(a, b) {
3 | return a + b
4 | }
5 |
--------------------------------------------------------------------------------
/test-webpack/src/common.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | body {
7 | width: 100%;
8 | height: 200%;
9 | }
10 |
--------------------------------------------------------------------------------
/test-webpack/dist/pageA-d7ac82de795ddf50c9df43291d77b4c8.css:
--------------------------------------------------------------------------------
1 | p{width:100px;height:200px}div{width:200px}*{padding:0;margin:0}body{width:100%;height:200%}
--------------------------------------------------------------------------------
/test-webpack/dist/pageB-56185455ea60f01155a65497e9bf6c85.css:
--------------------------------------------------------------------------------
1 | *{padding:0;margin:0}body{width:100%;height:200%}body{background:#ff0}span{display:inline-block;width:100px}
--------------------------------------------------------------------------------
/test-webpack/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Getting Started
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test-cross/cors/server.js:
--------------------------------------------------------------------------------
1 | const http = require('http')
2 | http.createServer((req, res) => {
3 | res.writeHead(200, {
4 | 'Access-Control-Allow-Origin': 'http://127.0.0.1:8080',
5 | 'Content-Type': 'text/html;charset=utf-8'
6 | })
7 | res.end('这是你要的数据:1111')
8 | })
9 |
--------------------------------------------------------------------------------
/test-cross/postMessage/server/data.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test-webpack/src/a.js:
--------------------------------------------------------------------------------
1 | const sum = require('./common.js')
2 | const _ = require('lodash')
3 | function component() {
4 | var element = document.createElement('div')
5 |
6 | // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
7 | element.innerHTML = _.join(['Hello', 'webpack'], ' ')
8 |
9 | return element
10 | }
11 |
12 | document.body.appendChild(component())
13 |
--------------------------------------------------------------------------------
/test-webpack/src/b.js:
--------------------------------------------------------------------------------
1 | require('./b.less')
2 | const sum = require('./common.js')
3 | const _ = require('lodash')
4 |
5 | function component() {
6 | var element = document.createElement('div')
7 |
8 | // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
9 | element.innerHTML = _.join(['Hello', 'webpack'], ' ')
10 |
11 | return element
12 | }
13 |
14 | document.body.appendChild(component())
15 |
--------------------------------------------------------------------------------
/test-cross/jsonp/server.js:
--------------------------------------------------------------------------------
1 | const url = require('url')
2 | const http = require('http')
3 | http
4 | .createServer((req, res) => {
5 | const data = {
6 | a: 10
7 | }
8 |
9 | const callback = url.parse(req.url, true).query.callback
10 | res.writeHead(200)
11 | res.end(`${callback}(${JSON.stringify(data)})`)
12 | })
13 | .listen(3000, '127.0.0.1')
14 | console.log('服务启动,监听127.0.0.1')
15 |
--------------------------------------------------------------------------------
/test-cross/jsonp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | test jsonp
9 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/test-cross/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-cross",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "jsonp": "node ./jsonp/server.js & http-server ./jsonp",
8 | "cors": "node ./cors/server.js & http-server ./cors",
9 | "proxy": "node ./serverProxy/server.js",
10 | "postMessage":
11 | "http-server ./postMessage/client/ -p 8080 & http-server ./postMessage/server/ -p 8081"
12 | },
13 | "author": "lip.fan",
14 | "license": "ISC",
15 | "dependencies": {
16 | "http-server": "^0.11.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/vue.md:
--------------------------------------------------------------------------------
1 | #### Vue 相关知识点总结
2 |
3 | vue 在初始化的时候实际上执行的方法
4 |
5 | ```js
6 | initLifecycle(vm)
7 | initEvents(vm)
8 | initRender(vm)
9 | callHook(vm, 'beforeCreate')
10 | initInjection(vm)
11 | initProps(vm)
12 | initMethods(vm)
13 | initData(vm)
14 | initComputed(vm)
15 | initWatch(vm)
16 | initPrivode(vm)
17 | callHook(vm, 'created')
18 | if (vm.$option.el) {
19 | vm.$mount(vm.$option.el)
20 | }
21 | ```
22 |
23 | mounted 调用逻辑判断是否存在 template 选项有的话就直接获取 dom 字符串。没有的话就是通过 el 选择器选择出 dom。在获得模版后,会将模版编译成为渲染函数。这里生成的渲染函数有两个一个是静态节点的渲染函数,一个是动态的渲染函数。最后会把渲染函数挂在 vue.$options 上面。最后就调用缓存下来的$mount
24 |
--------------------------------------------------------------------------------
/webpack.md:
--------------------------------------------------------------------------------
1 | ### webpack 相关知识点总结
2 |
3 | **chunkid 和 moduleid**
4 |
5 | * 每个 chunkid 对应的是一个 js 文件
6 | * 每个 moduleid 对应的是一个个 js 文件的内容的模块(一个 js 文件里面可以 require 多个资源,每 个资源分配一个 moduleid)
7 |
8 | **compiler 和 compilation**
9 |
10 | * compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。
11 |
12 | * compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。
13 |
--------------------------------------------------------------------------------
/test-webpack/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-webpack",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "webpack --color --config ./webpack.config.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "css-loader": "^0.28.7",
14 | "extract-text-webpack-plugin": "^3.0.2",
15 | "less": "^2.7.3",
16 | "less-loader": "^4.0.5",
17 | "lodash": "^4.17.4",
18 | "style-loader": "^0.19.0",
19 | "webpack": "^3.8.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Blog
2 |
3 | A blog for learning knowledge
4 |
5 | ## Articles
6 |
7 | * [x] 1、[从观察者模式(发布订阅模式)到 vue 响应系统](https://github.com/Copyes/Articles/blob/master/observer.md)
8 | * [x] 2、[html&css 知识点总结](https://github.com/Copyes/Articles/blob/master/html%26css.md)
9 | * [x] 3、[javascript 知识点总结](https://github.com/Copyes/Articles/blob/master/javascript.md)
10 | * [x] 4、[原型和原型链的简单总结](https://github.com/Copyes/Articles/blob/master/prototype.md)
11 | * [x] 5、[http 知识点总结](https://github.com/Copyes/Articles/blob/master/http.md)
12 | * [x] 6、[XSS 和 CSRF 知识点总结](https://github.com/Copyes/Articles/blob/master/xss%26csrf.md)
13 |
--------------------------------------------------------------------------------
/test-cross/cors/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | test cors
9 |
10 |
11 |
12 |
13 |
14 |
24 |
25 |
--------------------------------------------------------------------------------
/test-html&css/3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Flex布局
9 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/test-cross/serverProxy/server.js:
--------------------------------------------------------------------------------
1 | const url = require('url')
2 | const http = require('http')
3 | const https = require('https')
4 |
5 | http
6 | .createServer((req, res) => {
7 | const path = url.parse(req.url).path.slice(1)
8 | if (path === 'topics') {
9 | https.get('https://cnodejs.org/api/v1/topics', resp => {
10 | let data = ''
11 | resp.on('data', chunk => {
12 | data += chunk
13 | })
14 | resp.on('end', () => {
15 | res.writeHead(200, {
16 | 'Content-Type': 'application/json; charset=utf-8'
17 | })
18 | res.end(data)
19 | })
20 | })
21 | }
22 | })
23 | .listen(3000, '127.0.0.1')
24 | console.log('The server is listening to 127.0.0.0')
--------------------------------------------------------------------------------
/test-cross/postMessage/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | postMessage
9 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test-html&css/4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 用 Flex 画出一个直径 100px 的圆,并放在屏幕中间
9 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/test-html&css/5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | css实现垂直居中
9 |
34 |
35 |
36 |
37 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/test-webpack/dist/pageA-8ddb2f0f51a8139475bb.js:
--------------------------------------------------------------------------------
1 | webpackJsonp(["pageA"],{
2 |
3 | /***/ "645S":
4 | /***/ (function(module, exports) {
5 |
6 | // removed by extract-text-webpack-plugin
7 |
8 | /***/ }),
9 |
10 | /***/ "MvGc":
11 | /***/ (function(module, exports, __webpack_require__) {
12 |
13 | /* WEBPACK VAR INJECTION */(function(module) {__webpack_require__("645S")
14 | module.export = function sum(a, b) {
15 | return a + b
16 | }
17 |
18 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__("3IRH")(module)))
19 |
20 | /***/ }),
21 |
22 | /***/ "aQZI":
23 | /***/ (function(module, exports, __webpack_require__) {
24 |
25 | const sum = __webpack_require__("MvGc")
26 | const _ = __webpack_require__("M4fF")
27 | function component() {
28 | var element = document.createElement('div')
29 |
30 | // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
31 | element.innerHTML = _.join(['Hello', 'webpack'], ' ')
32 |
33 | return element
34 | }
35 |
36 | document.body.appendChild(component())
37 |
38 |
39 | /***/ })
40 |
41 | },["aQZI"]);
--------------------------------------------------------------------------------
/async.md:
--------------------------------------------------------------------------------
1 | async函数是generator函数的语法糖
2 |
3 | 同样的一个函数用async替换的时候只需要吧 function*(){}替换成 async 把yield替换成await即可
4 |
5 | 但是async函数有4点改进
6 |
7 | 1. 内置执行器 (generator需要用co模块)
8 | 2. 更好的语义 await表示需要等待异步结果
9 | 3. 更广的适用性
10 | 4. 返回值与generator不同返回Promise对象(即使你返回的是一个值也会被包装成Promise.resolve(值))
11 |
12 | async返回的是Promise对象,可以再被await做为参数
13 |
14 | async函数可以放在对象,类,表达式,函数声明,箭头函数中
15 |
16 | async的错误机制是个难点
17 |
18 | > async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。
19 |
20 | async函数返回的promise对象,必须等return前的所有await的promise执行完成之后才会执行
21 |
22 | unhandledRejection事件可以捕获错误
23 |
24 | await后面是一个promise对象如果不是会立即被转化成一个resolve的promise对象
25 |
26 | await中的任何一个promise被reject之后都会中断后续执行,如果不想因为其中一个reject就影响后面的执行可以使用try...catch,或者还有一种方法是对await的promise直接调用.catch
27 |
28 | 在async函数中如果两个异步可以并行,就不要写成串行,并行不一定非要用promise.all
29 |
30 |
31 |
32 | 注意点:
33 | - [ ] yield 和 await 后面可以是原始类型的值(string,number,boolean)(实际测试能返回任何值)或者promise对象, 但是co模块约定yield后面只能返回Thunk函数或Promise对象
34 | - [ ] async 函数执行过程如果报错可以在最后返回的promise里.catch捕获错误
35 | - [ ] async 函数在执行的时候一旦遇到await就会返回Promise
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test-html&css/1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 圣杯布局
9 |
40 |
41 |
42 |
43 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/test-html&css/2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 双飞翼布局
9 |
38 |
39 |
40 |
41 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/careful.md:
--------------------------------------------------------------------------------
1 | ### 小程序审核注意事项
2 |
3 | 以下为育儿宝和育儿宝成长记录以及早教宝小程序开发以及审核相关注意事项。
4 |
5 | **审核**
6 |
7 | > 1、类目不完善或者是类目选择不当
8 |
9 | 提交审核前一定要仔细看区分,可以了解下竞品发的是什么类目。
10 |
11 | > 2、“功能不完善/功能不完整”
12 |
13 | 这个有时候是审核人员不会用误以为你的小程序没开发完整,如果你确定没问题的话可以多提交一次试试。
14 |
15 | > 3、含有声音视频类目
16 |
17 | 这个就要把音视频类目选择上
18 |
19 | > 4、不得展示和推荐第三方小程序
20 |
21 | 不能做小程序导航、小程序排行榜之类的产品或功能。
22 |
23 | > 5、不能含有诱导分享的内容
24 |
25 | 这个已经不用多说了,微信在诱导分享方面的规则有多严大家应该都了解了。
26 |
27 | > 6、必须登录才能体验的小程序,必须提供测试账号
28 |
29 | 测试账号目前是产品 3 君提供了一个自己的账号如有需要请自行想法,账号如下:
30 |
31 | 账号:xiaohao3jun
32 | 密码:ylj9694
33 |
34 | > 7、一些建议
35 |
36 | * 1.尽量早提交,虽然目前小程序的审核期已经比公测时短了不少,但是审核依然严格,早提交早发现问题。
37 | * 2.仔细阅读官方文档!!!这点非常重要!不看文档活该一直被拒。
38 | * 3.可以通过邮件跟微信团队沟通。
39 |
40 | **注意**
41 |
42 | * 1、育儿宝 APP 和育儿成长记录是两个小程序共用一套代码,通过 type 来区分。
43 |
44 | ```js
45 | // utils下面的user.js文件中
46 | method: 'POST',
47 | data: {
48 | method: 'yuerbao.user.applet.auth',
49 | code,
50 | type: 14 // 7 是育儿宝app , 14是育儿成长记录
51 | },
52 | ```
53 |
54 | * 2、架构问题
55 |
56 | 目前育儿宝 app 小程序和早教宝的架构是不同的。育儿宝这边是一年半前小程序才出来的时候封装的。育儿宝是前段时间才封装的。育儿宝小程序主要是异步回调的开发方式,早教宝主要是同步的开发方式。(如果有问题育儿宝可以找金金,早教宝找万利)
57 |
58 | * 3、后期可以思考的点
59 |
60 | 1、早教宝和育儿宝中的落地页可以换成小程序即分享出去的是小程序。
61 |
62 | 2、小程序来做拉新的活动
63 |
--------------------------------------------------------------------------------
/test-webpack/dist/pageA-b5b4e2893bce99fd5c57.js:
--------------------------------------------------------------------------------
1 | webpackJsonp(["pageA"],{
2 |
3 | /***/ "645S":
4 | /***/ (function(module, exports) {
5 |
6 | // removed by extract-text-webpack-plugin
7 |
8 | /***/ }),
9 |
10 | /***/ "LJbA":
11 | /***/ (function(module, exports) {
12 |
13 | // removed by extract-text-webpack-plugin
14 |
15 | /***/ }),
16 |
17 | /***/ "MvGc":
18 | /***/ (function(module, exports, __webpack_require__) {
19 |
20 | /* WEBPACK VAR INJECTION */(function(module) {__webpack_require__("645S")
21 | module.export = function sum(a, b) {
22 | return a + b
23 | }
24 |
25 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__("3IRH")(module)))
26 |
27 | /***/ }),
28 |
29 | /***/ "aQZI":
30 | /***/ (function(module, exports, __webpack_require__) {
31 |
32 | __webpack_require__("LJbA")
33 | const sum = __webpack_require__("MvGc")
34 | const _ = __webpack_require__("M4fF")
35 | function component() {
36 | var element = document.createElement('div')
37 |
38 | // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
39 | element.innerHTML = _.join(['Hello', 'webpack'], ' ')
40 |
41 | return element
42 | }
43 |
44 | document.body.appendChild(component())
45 |
46 |
47 | /***/ })
48 |
49 | },["aQZI"]);
--------------------------------------------------------------------------------
/test-webpack/dist/pageB-34be879b3374ac9b2072.js:
--------------------------------------------------------------------------------
1 | webpackJsonp(["pageB"],{
2 |
3 | /***/ "645S":
4 | /***/ (function(module, exports) {
5 |
6 | // removed by extract-text-webpack-plugin
7 |
8 | /***/ }),
9 |
10 | /***/ "JIOT":
11 | /***/ (function(module, exports, __webpack_require__) {
12 |
13 | __webpack_require__("lhZZ")
14 | const sum = __webpack_require__("MvGc")
15 | const _ = __webpack_require__("M4fF")
16 |
17 | function component() {
18 | var element = document.createElement('div')
19 |
20 | // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
21 | element.innerHTML = _.join(['Hello', 'webpack'], ' ')
22 |
23 | return element
24 | }
25 |
26 | document.body.appendChild(component())
27 |
28 |
29 | /***/ }),
30 |
31 | /***/ "MvGc":
32 | /***/ (function(module, exports, __webpack_require__) {
33 |
34 | /* WEBPACK VAR INJECTION */(function(module) {__webpack_require__("645S")
35 | module.export = function sum(a, b) {
36 | return a + b
37 | }
38 |
39 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__("3IRH")(module)))
40 |
41 | /***/ }),
42 |
43 | /***/ "lhZZ":
44 | /***/ (function(module, exports) {
45 |
46 | // removed by extract-text-webpack-plugin
47 |
48 | /***/ })
49 |
50 | },["JIOT"]);
--------------------------------------------------------------------------------
/test-html&css/6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Document
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
47 |
48 |
--------------------------------------------------------------------------------
/test-webpack/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
4 | module.exports = {
5 | entry: {
6 | pageA: './src/a.js',
7 | pageB: './src/b.js',
8 | vendor: ['lodash']
9 | },
10 | output: {
11 | filename: '[name]-[chunkhash].js',
12 | path: path.resolve(__dirname, 'dist')
13 | },
14 | module: {
15 | rules: [
16 | {
17 | test: /\.css$/,
18 | use: ExtractTextPlugin.extract({
19 | fallback: 'style-loader',
20 | use: ['css-loader?minimize']
21 | })
22 | },
23 | {
24 | test: /\.less$/, // ['css-loader?minimize&-autoprefixer!postcss-loader', 'less-loader']
25 | use: ExtractTextPlugin.extract({
26 | fallback: 'style-loader',
27 | use: ['css-loader?minimize', 'less-loader']
28 | })
29 | }
30 | ]
31 | },
32 | plugins: [
33 | new ExtractTextPlugin('[name]-[contenthash].css'),
34 | new webpack.HashedModuleIdsPlugin(),
35 | new webpack.NamedChunksPlugin(chunk => {
36 | if (chunk.name) {
37 | return chunk.name
38 | }
39 |
40 | return chunk
41 | .mapModules(m => path.relative(m.context, m.request))
42 | .join('_')
43 | }),
44 | new webpack.optimize.CommonsChunkPlugin({
45 | name: 'vendor',
46 | minChunks: Infinity
47 | }),
48 | new webpack.optimize.CommonsChunkPlugin({
49 | name: 'runtime'
50 | })
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/koa2/compose.js:
--------------------------------------------------------------------------------
1 | function compose(middleware) {
2 | // 传入的 middleware 参数必须是数组
3 | if (!Array.isArray(middleware))
4 | throw new TypeError('Middleware stack must be an array!')
5 | // middleware 数组的元素必须是函数
6 | for (const fn of middleware) {
7 | if (typeof fn !== 'function')
8 | throw new TypeError('Middleware must be composed of functions!')
9 | }
10 |
11 | // 返回一个函数闭包, 保持对 middleware 的引用
12 | return function(context, next) {
13 | // 这里的 context 参数是作为一个全局的设置, 所有中间件的第一个参数就是传入的 context, 这样可以
14 | // 在 context 中对某个值或者某些值做"洋葱处理"
15 |
16 | // 解释一下传入的 next, 这个传入的 next 函数是在所有中间件执行后的"最后"一个函数, 这里的"最后"并不是真正的最后,
17 | // 而是像上面那个图中的圆心, 执行完圆心之后, 会返回去执行上一个中间件函数(middleware[length - 1])剩下的逻辑
18 |
19 | // index 是用来记录中间件函数运行到了哪一个函数
20 | let index = -1
21 | // 执行第一个中间件函数
22 | return dispatch(0)
23 |
24 | function dispatch(i) {
25 | // i 是洋葱模型的记录已经运行的函数中间件的下标, 如果一个中间件里面运行两次 next, 那么 i 是会比 index 小的.
26 | // 如果对这个地方不清楚可以查看下面的图
27 | if (i <= index)
28 | return Promise.reject(new Error('next() called multiple times'))
29 | index = i
30 | let fn = middleware[i]
31 | if (i === middleware.length) {
32 | // 这里的 next 就是一开始 compose 传入的 next, 意味着当中间件函数数列执行完后, 执行这个 next 函数, 即圆心
33 | fn = next
34 | }
35 | // 如果没有函数, 直接返回空值的 Promise
36 | if (!fn) return Promise.resolve()
37 | try {
38 | // 为什么这里要包一层 Promise?
39 | // 因为 async 需要后面是 Promise, 然后 next 函数返回值就是 dispatch 函数的返回值, 所以运行 async next(); 需要 next 包一层 Promise
40 | // next 函数是固定的, 可以执行下一个函数
41 | return Promise.resolve(
42 | fn(context, function next() {
43 | return dispatch(i + 1)
44 | })
45 | )
46 | } catch (err) {
47 | return Promise.reject(err)
48 | }
49 | }
50 | }
51 | }
52 |
53 | async function first(ctx, next) {
54 | console.log('1')
55 | // async 与 co + yield 的模型不同, await 是需要后面是 promise 的函数, 并且自己执行一次, 而 co 是自己拿到 value 然后帮你自动执行.
56 | await next()
57 | await next() // 两次调用 next
58 | console.log(ctx)
59 | }
60 |
61 | async function second(ctx, next) {
62 | console.log('2')
63 | await next()
64 | }
65 |
66 | async function third(ctx, next) {
67 | console.log('3')
68 | await next()
69 | console.log('4')
70 | }
71 |
72 | const middleware = [first, second, third]
73 |
74 | const com = compose(middleware)
75 |
76 | com('ctx', function() {
77 | console.log('hey')
78 | })
79 |
--------------------------------------------------------------------------------
/test-javascript/4.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | var _createClass = (function() {
4 | function defineProperties(target, props) {
5 | for (var i = 0; i < props.length; i++) {
6 | var descriptor = props[i]
7 | descriptor.enumerable = descriptor.enumerable || false
8 | descriptor.configurable = true
9 | if ('value' in descriptor) descriptor.writable = true
10 | Object.defineProperty(target, descriptor.key, descriptor)
11 | }
12 | }
13 | return function(Constructor, protoProps, staticProps) {
14 | if (protoProps) defineProperties(Constructor.prototype, protoProps)
15 | if (staticProps) defineProperties(Constructor, staticProps)
16 | return Constructor
17 | }
18 | })()
19 |
20 | function _possibleConstructorReturn(self, call) {
21 | if (!self) {
22 | throw new ReferenceError(
23 | "this hasn't been initialised - super() hasn't been called"
24 | )
25 | }
26 | return call && (typeof call === 'object' || typeof call === 'function')
27 | ? call
28 | : self
29 | }
30 |
31 | function _inherits(subClass, superClass) {
32 | if (typeof superClass !== 'function' && superClass !== null) {
33 | throw new TypeError(
34 | 'Super expression must either be null or a function, not ' +
35 | typeof superClass
36 | )
37 | }
38 | subClass.prototype = Object.create(superClass && superClass.prototype, {
39 | constructor: {
40 | value: subClass,
41 | enumerable: false,
42 | writable: true,
43 | configurable: true
44 | }
45 | })
46 | if (superClass)
47 | Object.setPrototypeOf
48 | ? Object.setPrototypeOf(subClass, superClass)
49 | : (subClass.__proto__ = superClass)
50 | }
51 |
52 | function _classCallCheck(instance, Constructor) {
53 | if (!(instance instanceof Constructor)) {
54 | throw new TypeError('Cannot call a class as a function')
55 | }
56 | }
57 |
58 | var A = (function() {
59 | function A() {
60 | _classCallCheck(this, A)
61 | }
62 |
63 | _createClass(A, [
64 | {
65 | key: 'a',
66 | value: function a() {}
67 | }
68 | ])
69 |
70 | return A
71 | })()
72 |
73 | var B = (function(_A) {
74 | _inherits(B, _A)
75 |
76 | function B() {
77 | _classCallCheck(this, B)
78 |
79 | return _possibleConstructorReturn(
80 | this,
81 | (B.__proto__ || Object.getPrototypeOf(B)).call(this)
82 | )
83 | }
84 |
85 | _createClass(B, [
86 | {
87 | key: 'b',
88 | value: function b() {}
89 | }
90 | ])
91 |
92 | return B
93 | })(A)
94 |
--------------------------------------------------------------------------------
/test-webpack/dist/bundle.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 | /******/
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 | /******/
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId]) {
10 | /******/ return installedModules[moduleId].exports;
11 | /******/ }
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ i: moduleId,
15 | /******/ l: false,
16 | /******/ exports: {}
17 | /******/ };
18 | /******/
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 | /******/
22 | /******/ // Flag the module as loaded
23 | /******/ module.l = true;
24 | /******/
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 | /******/
29 | /******/
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 | /******/
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 | /******/
36 | /******/ // define getter function for harmony exports
37 | /******/ __webpack_require__.d = function(exports, name, getter) {
38 | /******/ if(!__webpack_require__.o(exports, name)) {
39 | /******/ Object.defineProperty(exports, name, {
40 | /******/ configurable: false,
41 | /******/ enumerable: true,
42 | /******/ get: getter
43 | /******/ });
44 | /******/ }
45 | /******/ };
46 | /******/
47 | /******/ // getDefaultExport function for compatibility with non-harmony modules
48 | /******/ __webpack_require__.n = function(module) {
49 | /******/ var getter = module && module.__esModule ?
50 | /******/ function getDefault() { return module['default']; } :
51 | /******/ function getModuleExports() { return module; };
52 | /******/ __webpack_require__.d(getter, 'a', getter);
53 | /******/ return getter;
54 | /******/ };
55 | /******/
56 | /******/ // Object.prototype.hasOwnProperty.call
57 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58 | /******/
59 | /******/ // __webpack_public_path__
60 | /******/ __webpack_require__.p = "";
61 | /******/
62 | /******/ // Load entry module and return exports
63 | /******/ return __webpack_require__(__webpack_require__.s = 0);
64 | /******/ })
65 | /************************************************************************/
66 | /******/ ([
67 | /* 0 */
68 | /***/ (function(module, exports) {
69 |
70 | function component() {
71 | var element = document.createElement('div')
72 |
73 | // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
74 | element.innerHTML = _.join(['Hello', 'webpack'], ' ')
75 |
76 | return element
77 | }
78 |
79 | document.body.appendChild(component())
80 |
81 |
82 | /***/ })
83 | /******/ ]);
--------------------------------------------------------------------------------
/xss&csrf.md:
--------------------------------------------------------------------------------
1 | ### 关于 XSS 攻击和 CSRF 攻击的总结
2 |
3 | > 对于跨站脚本攻击(XSS 攻击)的理解和总结
4 |
5 | **什么是 XSS 攻击**
6 |
7 | * XSS 是跨站脚本攻击的缩写,是一种网站应用程序的安全漏洞攻击,是代码注入的一种。
8 | * 通常是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
9 | * 这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java,VBScript,ActiveX,Flash 或者甚至是普通的 HTML。
10 | * 攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容。
11 |
12 | **XSS 攻击基本原理---代码注入**
13 |
14 | 在 web 的世界里有各种各样的语言,于是乎对于语句的解析大家各不相同,有一些语句在一种语言里是合法的,但是在另外一种语言里是非法的。这种二义性使得黑客可以用代码注入的方式进行攻击——将恶意代码注入合法代码里隐藏起来,再诱发恶意代码,从而进行各种各样的非法活动。只要破坏跨层协议的数据/指令的构造,我们就能攻击。历史悠久的 SQL 注入和 XSS 注入都是这种攻击方式的典范。现如今,随着参数化查询的普及,我们已经离 SQL 注入很远了。但是,历史同样悠久的 XSS 却没有远离我们。
15 | XSS 的基本实现思路很简单——比如持久型 XSS 通过一些正常的站内交互途径,例如发布评论,提交含有 JavaScript 的内容文本。这时服务器端如果没有过滤或转义掉这些脚本,作为内容发布到了页面上,其他用户访问这个页面的时候就会运行这些脚本,从而被攻击。
16 |
17 | **攻击分类**
18 |
19 | * 反射型 XSS
20 |
21 | 反射性 XSS,也就是被动的非持久性 XSS。诱骗用户点击 URL 带攻击代码的链接,服务器解析后响应,在返回的响应内容中隐藏和嵌入攻击者的 XSS 代码,被浏览器执行,从而攻击用户。
22 | URL 可能被用户怀疑,但是可以通过短网址服务将之缩短,从而隐藏自己。
23 |
24 | * 持久型 XSS
25 |
26 | 也叫存储型 XSS——主动提交恶意数据到服务器,攻击者在数据中嵌入代码,这样当其他用户请求后,服务器从数据库中查询数据并发给用户,用户浏览此类页面时就可能受到攻击。可以描述为:恶意用户的 HTML 或 JS 输入服务器->进入数据库->服务器响应时查询数据库->用户浏览器。
27 |
28 | **防范**
29 |
30 | * 使用 XSS Filter
31 |
32 | 输入过滤,对用户提交的数据进行有效性验证,仅接受指定长度范围内并符合我们期望格式的的内容提交,阻止或者忽略除此外的其他任何数据。
33 |
34 | 输出转义,当需要将一个字符串输出到 Web 网页时,同时又不确定这个字符串中是否包括 XSS 特殊字符,为了确保输出内容的完整性和正确性,输出 HTML 属性时可以使用 HTML 转义编码(HTMLEncode)进行处理,输出到
136 |
137 |