-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
77 lines (77 loc) · 24.5 KB
/
search.xml
File metadata and controls
77 lines (77 loc) · 24.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[setInterval 实现轮询]]></title>
<url>%2F2018%2F04%2F07%2FsetInterval-%E5%AE%9E%E7%8E%B0%E8%BD%AE%E8%AF%A2%2F</url>
<content type="text"><![CDATA[起因最近做项目遇到的问题:当用户添加评论后,数据必须刷新才能从 mongodn 中读取出来;于是就想到两种解决办法 第一种是,在把数据添加进数据库的同时页面上先手动添加“假”数据,等下次用户再看时,就会从数据库中读取出来 第二种就是,用 setInterval 来实现轮询,每隔 2s 从数据库中获取一次数据(比较耗费性能,但目前还未想到更好的解决方法) setInterval 的参数问题一般我们使用 setInterval 时都会传入匿名函数 1234567891011121314//无参数时setInterval(function(){ console.log(1)}, 1000)//有参数时setInerval(function(name) { console.log('hello '+name) //由于无法传递参数,所以为 'hello undefined'}, 1000)//当有参数并且传入时setInerval((function(name) { console.log('hello '+name) //就成了IIFE})('嘿哈'), 1000) 如何可以传入参数并正常运行?第一种:将函数调用改为字符串12345function renderUserData(id) { console.log(id) //...}setInterval("renderUserData(articleId)", 1000) 第二种:使用闭包返回无参数函数123456function renderUserData(id) { return function() { console.log(id) }}setInterval(renderUserData(articleId), 1000) 第三种:改进原生的 setInterval思路与第二种相同:都是外层接受参数,返回一个无参数的函数123456789let old = setIntervalwindow.setInterval = function(callback, timeout, param) { const args = [].slice.call(arguments, 2) const _cb = function () { callback.apply(null, args) } old(_cb, timeout)} The End]]></content>
<categories>
<category>项目经验</category>
</categories>
<tags>
<tag>JS小技巧</tag>
</tags>
</entry>
<entry>
<title><![CDATA[web安全]]></title>
<url>%2F2018%2F03%2F25%2Fweb%E5%AE%89%E5%85%A8%2F</url>
<content type="text"><![CDATA[web安全是如何提出的?随着互联网的发展,我们的个人财富、信息等都会存储在互联网上,这时就会有不少神秘人想要利用 web 网页的漏洞获取我们的财富或者利用我们的信息获得财富,内行的人给这些神秘人起了个代号,叫做 “黑客”为了保护我们的财富及信息,就提出了web安全这个概念 web的攻击手段有哪些?目前比较出名的有XSS,CSRF,DDOS;本篇文章简单介绍一下这些手段的原理及如何防范(个人理解,可能有误) XSS概念XSS(Cross-Site-Script)跨站脚本攻击,由于简写与CSS层叠样式表重复,所以就叫X;XSS 的原理就是往网页中注入恶意脚本代码,当用户访问该网页时就会获取到带有恶意脚本代码的网页;通过恶意脚本,坏人就会获取到用户的登陆态信息(cookie等)XSS 又可细分为反射型,存储型,DOM Base 型 反射型 XSS反射型 XSS,又称非持久型 XSS 原理通过用户点击来将恶意脚本反射给用户 举例某购物界面地址为:http://localhost:3000/goods.html当搜索商品时,请求的 url 会变为 http://localhost:3000/goods.html?sort=book在服务端中,会读取请求参数sort的值,拿到结果后返回给前端如果服务端没有对请求参数做任何处理,如下:1234567router.get('/goods.html', async (ctx) => { const sort = ctx.query.sort ctx.body = ` <p style="font-size: 40px; padding: 10px;">当前分类: ${sort}</p> ${getSortGoods(sort)} `}) 此时,如果给 sort 的值传入<script>console.log(document.cookie)</script>就可以拿到该用户的登陆态了那么如何忽悠用户上当呢?往网页中注入图片链接<a href='goods.html?sort=<script>alert(1)</script>'><img src="xxx" alt="嘿嘿嘿"/></a>如果图片做得好,总有用户会(上当)点击 为什么叫反射型(非持久型)因为是根据参数来返回值,数据并不会保留到服务器内部,所以是非持久型的;通过参数把内容反射给用户,所以叫反射型 如何防范XSS 的本质就是通过脚本攻击,所以让脚本失效就 Ok 了,最简单的做法就是转义字符12345678function htmlEscape(str) { return String(str) .replace(/&/g, '&amp;') .replace(/"/g, '&quot;') .replace(/'/g, '&#39;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;');} 存储型 XSS存储型 XSS,又叫持久型 XSS 原理利用网页漏洞,将恶意脚本存储在服务器上,每当有用户访问时就会触发恶意脚本;常见于社交网站和博客类网站 举例曾经某个写博客的平台出过事,对用户评论没有做处理,直接存储到服务器。若某用户评论<script>console.log(document.cookie)</script>,评论会被存储在服务器的评论列表中,每当有一位新的用户访问这篇文章时,就会把评论列表遍历一遍展示出来,此时该用户的cookie就会打印出来;当然,坏人一般会把cookie发到他的服务器上 如何防范与反射型 XSS 类似,有一点要注意就是不能光在前端对用户的输入进行处理;有时坏人会在服务器端模拟请求,避开前端的转义,所以也要对服务端进行处理 DOM Based型 XSS原理发生在浏览器端 DOM 解析的时候,由于 Javascript 修改页面 DOM 结构而发起的攻击;So,如果页面的 JS 脚本没有漏洞就不会发起该攻击 举例12345678<div id="content"></div><input type="text" id="text"/><button onclick="addText()">Add</button>//往页面中添加文本function addText() { var htmlText = '<a href="' + $('#text').val() +'">hhh</a>' $('#content').html(htmlText)} 输入 " onclick="alert(1)" // 查看 如何防范把用户输入的敏感属性(onclick等)用 ‘’ 替代掉即可 XSS钓鱼如何拿XSS钓鱼? 通过评论在页面注入钓鱼网站链接 <a href="http://www.hacker.com">王者荣耀热门活动</a> 用户浏览钓鱼网站,输入账号、密码 账号、密码发送至坏人的服务器上 完成 CSRF概念CSRF(Cross-site-request-forgery)跨站点请求伪造;攻击者通过模拟用户的登陆态来进行一系列操作。 举例 用户登录银行页面 银行的服务器会给用户设置一个唯一标识的 cookie 攻击者会弄一个图片诱导你去点击 如果你登陆完银行没有退出登录,点击完上个页面,攻击者就会利用你的cookie 来发起转账请求,再一看,钱就没了 防御手段referer 验证用户访问页面时,在请求头中都会带有referer这个字段,表示用户从哪个页面发起的请求,如果不是同域下的,则拒绝处理请求;上述过程是从坏人的服务器上发起的请求,referer不是来自同域,就会拒绝处理请求12345// referer 判断,防止 CSRFconst isLegalReferer = (ctx) => { const referer = ctx.request.header.referer return /https?:\/\/localhost:3000/.test(referer)} token 验证由于请求头referer可能会被模拟,所以 token 验证更加常用在客户端发起请求时设置token为用算法加密过的 cookie,在服务器端用同样的算法计算出token,如果不一致,则拒绝处理请求;因为跨域不会读到本域下的 cookie,所以比较安全 XSS 蠕虫概念XSS 蠕虫本质上是 XSS + CSRF;不需要用户点击,即可大范围传播。见上图银行转账的例子,如果在 bank.com 里直接注入恶意脚本,那么第三步和第四步就可以省略了;用户就算不点击,也可直接在本页面中就可发起转账攻击。 如何防范既然本质上是 XSS + CSRF,那么做好这两个的防范即可。对于比较重要的请求,可以通过给用户发送验证码来进行确认 DDOS 攻击概念分布式拒绝服务(Distributed Denial of Service),坏人通过操纵大量电脑发起非正常请求来耗尽页面资源,使页面服务不能正常运行,从而导致正常访问的人无法访问 如何防范 验证码 通过 id 来限制请求频率 扩容加带宽 … 一些资料 互联网创业公司如何防御DDOS攻击 漫画告诉你什么时DDOS攻击]]></content>
<categories>
<category>安全</category>
</categories>
<tags>
<tag>XSS,CSRF</tag>
</tags>
</entry>
<entry>
<title><![CDATA[encodeURI与encodeURIComponent]]></title>
<url>%2F2018%2F03%2F18%2FencodeURI%E4%B8%8EencodeURIComponent%2F</url>
<content type="text"><![CDATA[以前认为 encodeURIComponent 是 encodeURI 的增强版,故一直使用前者,今天突然发现 encodeURIComponet 处理 url 会使其变成普通的字符串,特地研究了一下 从URL编码说起一般来说,URL 能使用的字符有英文字母(a-zA-Z),数字(0~9),特殊字符(-_.~)和一些保留字符(;,/?:@&=+$#) 如果使用了汉字,则要经过编码后才能访问;常用的编码方式有以下几种: encodeURI encodeURIComponent escape (废了) encodeURIencodeURI会将要编码的字符转为 UTF-8 的格式 12345encodeURI('http://www.百度.com')//"http://www.%E7%99%BE%E5%BA%A6.com" 此时转义没问题encodeURI('http://www.baidu.com?key1=?&key2=&')//"http://www.%E7%99%BE%E5%BA%A6.com?key1=?&key2=&" 此时一些保留字符(?, &)没有进行转义 这时就需要用encodeURIComponent了 encodeURIComponentencodeURIComponent 是用来编码 URI 参数的。它会跳过非转义字符(字母数字以及-_.!~*’())。但会转义 URL的 保留字符(;,/?:@&=+$#) 123encodeURIComponent('http://www.百度.com?key1=?&key2=&')// "http%3A%2F%2Fwww.%E7%99%BE%E5%BA%A6.com%3Fkey1%3D%3F%26key2%3D%26" 可以看到所有保留字符都被转义了,链接不能访问了,变成一个字符串 好的处理 url 的编码方法综合上面两者的特性,我们可以把 url 的参数交给 encodeURIComponent ,把其他部分交给 encodeURI 12encodeURI('http://www.百度.com?' + encodeURIComponent(key1) + '=' + encodeURIComponent(?))// "http://www.%E7%99%BE%E5%BA%A6.com?key1=%3F" URL 解码有编码,就有对应的解码 decodeURI decodeURIComponent The End]]></content>
<tags>
<tag>编码</tag>
</tags>
</entry>
<entry>
<title><![CDATA[工程化]]></title>
<url>%2F2018%2F01%2F29%2F%E5%B7%A5%E7%A8%8B%E5%8C%96%2F</url>
<content type="text"><![CDATA[工程化(What & Why)为了方便代码维护,我们要将相同功能的函数、对象等放入一个文件(模块),这样就会形成很多文件;但为了提高浏览器的渲染速度,我们又要尽量减少网络中请求的文件数; 既要考虑性能,又要考虑模块化,相互矛盾,怎么搞? 解决办法:开发时一套代码,发布到线上时一套合并压缩的代码。 如果手动处理,费时费力,于是就提出工程化。 工程化的实现grunt最早出现,每次操作都是文件读写,慢!配置相对繁琐。 gulp基于grunt缺点做得改进,基于文件流读写,快!配置也相对简单。 webpack早期只是一个打包工具,作为gulp的插件来使用;现在发展的相对全面,有以下特点: 任何文件都可以当模块 打包体积更小 打包更快 默认支持 AMD,Commonjs,ES6 modules webpack使用添加配置文件 webpack.config.js123456789101112131415var path = require('path');module.exports = { entry: './src/js/index.js', //入口文件 output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist') //文件处理后的输出目录 }, module: { }, plugins: [ ]} module 模块主要是针对特定类型的单文件进行处理 css-loader .css -> 可以加载的模块 babel-loader .es6 -> .js scss-loader .scss -> .css 在上面代码基础上增加打包css文件功能 npm 安装 style-loader 和 css-loader 模块 增加打包 css 的配置 1234567891011121314151617181920var path = require('path');module.exports = { entry: './src/js/index.js', //入口文件 output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist') //文件处理后的输出目录 }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, plugins: [ ]} plugins 模块来完成 loader 模块无法完成的事,比如: 压缩js 压缩图片 单独分离出css文件 … 在上面代码基础上实现压缩js功能 npm 安装 uglifyjs-webpack-plugin 增加插件配置 12345678910111213141516171819202122var path = require('path');//插件一般都是返回一个类,用时用 newvar UglifyJsPlugin = require('uglifyjs-webpack-plugin');module.exports = { entry: './src/js/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist') }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ] }, plugins: [ new UglifyJsPlugin() ]} 自动刷新本地开发流程保存代码 -> webpack构建 -> 刷新浏览器webpack-dev-server 可以自动完成这个过程与服务端 node 的 node-supervisior 类似 操作步骤: 先用 npm 安装 html-wepack-plugin 插件,将 index.html 也加入构建 将 index.html 从根目录移至 src,并删除其中 script 及 link 标签 在 webpack.config.js 中配置该插件 此时所有html,css,js源代码都在 src 目录下,打包后的文件都在 dist 目录下 全局安装 webpack-dev-server 运行 webpack-dev-server –open,修改 src 下文件,看是否自动刷新]]></content>
<categories>
<category>性能与工程化</category>
</categories>
<tags>
<tag>webpack</tag>
</tags>
</entry>
<entry>
<title><![CDATA[模块化开发]]></title>
<url>%2F2018%2F01%2F13%2F%E6%A8%A1%E5%9D%97%E5%8C%96%2F</url>
<content type="text"><![CDATA[概述为什么使用模块化开发 业务发展 -> 代码量变大,难以维护 -> 拆分代码成多个文件 -> 将特定功能的代码放在一个文件(即模块)中; 要解决的问题 避免命名冲突和变量污染 解决方案1、前缀命名空间: 能够有效解决,但却定义了大量的全局变量2、对象命名空间:3、IIFE: 管理模块依赖当引入的多个模块间存在相互依赖关系时,自动分析依赖、处理依赖关系,不需要手动维护 规范CommonJS规范 文件即模块 使用 module.exports / exports 暴露对外接口 使用 require 同步加载模块依赖 适用范围: 适合:node 服务端,文件存在本地硬盘 -> 加载快,可以同步加载 不适合:浏览器端,文件需要通过网络加载 -> 耗时,同步加载阻塞页面(需要异步加载所需模块)-> AMD规范 AMD规范 Asynchronous Module Definition 规范 CMD规范 Common Module Definition 规范 对比 AMD 与 CMD这两个现在都不常用,了解就好。 声明依赖模块时机不同 AMD 推崇依赖前置,在定义模块时就要声明其以来模块 CMD 推崇依赖就近,需要用时再 require() 1234567891011//CMDdefine(function(require, exports, module) { var a = require('./a'); a.doSomething();}) //AMDdefine(['./a', './b'], function() { a.doSomething(); b.doSomething();}) AMD的使用(require.js) define(‘模块标识’, ‘要依赖的模块’, ‘调用该模块要执行的函数’) 定义模块 reuqire(‘模块名’, ‘回调函数’) 调用模块 123456789101112131415161718192021//定义 moduleAdefine('moduleA', function(require, exports, module) { exports.getNum = function() { return 5; };});//定义moduleDdefine('moduleD', ['moduleA'], function(moduleA) { var index = moduleA.getNum(); return { addIndex: function() { index += 1; } }})//使用模块require('moduleD', function(moduleD) {}); CMD的使用(sea.js) 引入 SeaJS 的库 定义模块(define) 暴露模块接口(exports) 加载依赖模块(require) 12345678<script src="./sea.js"></script><script> define(function (require,exports,module) { // exports : 对外的接口 // requires : 依赖的模块 require('./a.js');//如果地址是一个模块的话,那么require的返回值就是模块中的exports });</script> ES6 模块标准设计思想一个JS文件就代表一个模块,你可以使用 import 和 export 来导入/导出模块中的东西 基本特点 自动开启严格模式,即使你没有写 use strict 每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域 模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等 每一个模块只加载一次,每一个 JS 只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取。 一个模块就是一个单例,或者说就是一个对象 更多 ES6模块指南 ES6入门之Module语法]]></content>
<categories>
<category>性能与工程化</category>
</categories>
<tags>
<tag>ES6</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<url>%2F2017%2F06%2F06%2Fhello-world%2F</url>
<content type="text"><![CDATA[Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment]]></content>
<categories>
<category>hexo</category>
</categories>
<tags>
<tag>hexo</tag>
</tags>
</entry>
<entry>
<title><![CDATA[webpacrk入门总结]]></title>
<url>%2F2017%2F06%2F06%2Fwebpacrk%E5%85%A5%E9%97%A8%E6%80%BB%E7%BB%93%2F</url>
<content type="text"><![CDATA[更新(2018.01.29):这篇写的不够好,请看另一篇有关webpack的:”工程化“ 什么是webpack webpakc可以看作是一个模块打包机,可以分析你的项目结构,帮你自动处理一些文件,如压缩、转化等,最终转化为适合浏览器使用的格式。 webpack与gulp工作方式的区别gulp:在一个配置文件中,指明对某些文件进行一些操作(编译,组合,压缩等)步骤之后,这个工具可以自动帮你处理这些文件 工作流程如下 webpack:通过指定的一个入口文件,webpack会从这个文件开始找到你项目所有的依赖文件,使用loaders处理它们,最后打包成一个浏览器可识别的JS(bundle.js)文件 工作流程如下 webpack的使用安装1234//全局安装npm install -g webpack//安装到你的项目目录npm instakk --save-dev webpack 假设项目结构如图所示 执行webpack的几种方法 终端输入 12345webpack entry file(入口文件的位置) bundled file(存放生成的bundle.js的位置) //按上面项目结构走//webpack非全局安装时(全局安装时可省略node_modules/.bin)node_modules/.bin/webpack app/main.js public/bundle.js 通过配置文件来使用webpack 在项目的根目录下建一个名为webpack.config.js的配置文件(本质上是一个JS模块),可以把所有与构建相关的信息放在里面 1234567module.exports = { entry: __dirname + "/app/main.js",//唯一入口文件 output: { path: __dirname + "/public",//打包后的文件存放的地方 filename: "bundle.js"//打包后输出文件的文件名 }} 通过配置package.json文件使用webpack 1234567891011121314{ "name": "webpack-sample-project", "version": "1.0.0", "description": "Sample webpack project", "scripts": { "start": "webpack", "comment": "相当于把npm的start命令指向webpack" }, "author": "Silence_JK", "license": "ISC", "devDependencies": { "webpack": "^2.6.1" }} 注:package.json中的脚本部分已默认在命令前添加node_modules/.bin,So don’t worry是否在全局安装了webpack webpack的一些常用功能 生成Source Maps(报错时方便调试,google浏览器中setting->勾选Enalbe JS source map),在wepack的配置文件中配置devtool选项即可 devtoo选项 配置结果 source-map 在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包文件的构建速度; cheap-module-source-map 在一个单独的文件中生成一个不带列映射的map,不带列映射提高项目构建速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便; eval-source-map 使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。不过在开发阶段这是一个非常好的选项,但是在生产阶段一定不要用这个选项; cheap-module-eval-source-map 这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点; loaders 通过使用不同的loader,webpack通过调用外部的脚本或工具可以对各种各样的格式的文件进行处理,比如将JSON文件转换为JavaScript文件,将下一代的JS文件(ES6,ES7)转换为现代浏览器可以识别的JS文件,对React的开发而言,合适的Loaders可以把React的JSX文件转换为JS文件。 loaders需要单独安装并且要在webpack.config.js下的module下配置常用配置项包括以下几个: test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须) loader:loader的名称(必须) include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选); query:为loaders提供额外的设置选项(可选) 例如:1234567891011121314151617181920212223242526272829//安装可以转换JSON的loadernpm install --save-dev json-loader//配置module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" }, module: {//在配置文件里添加JSON loader loaders: [ { test: /\.json$/, loader: "json" } ] }, devServer: { contentBase: "./public", colors: true, historyApiFallback: true, inline: true }} 插件(Plugins)插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。Loaders和Plugins是完全不同的东西 loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个 插件并不直接操作单个文件,它直接对整个构建过程其作用。 Webpack有很多内置插件,同时也有很多第三方插件,可以让我们完成更加丰富的功能。 使用插件的方法 要使用某个插件,我们需要通过npm安装它,然后要做的就是在webpack配置中的plugins关键字部分添加该插件的一个实例(plugins是一个数组)继续看例子,我们添加了一个实现版权声明的插件1234567891011121314151617181920//webpack.config.jsvar webpack = require('webpack');module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: {...}, module: { loaders: [ { test: /\.json$/, loader: "json" } ] }, plugins: [ new webpack.BannerPlugin("Copyright Flying Unicorns inc.")//在这个数组中new一个就可以了 ], devServer: {...}} 查看使用此插件后的JS打包文件localhost:8080/bundle.js 参考文章: 入门webpack,看这篇就够了]]></content>
<categories>
<category>性能与工程化</category>
</categories>
<tags>
<tag>webpack</tag>
</tags>
</entry>
</search>