-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.json
More file actions
1 lines (1 loc) · 57.4 KB
/
content.json
File metadata and controls
1 lines (1 loc) · 57.4 KB
1
{"meta":{"title":"Onions说前端 - 从未如此简单有趣","subtitle":"不要跟我谈理想,我的理想是不上班","description":"未来如何尚未定论,时间会给我答案。","author":"onions","url":"http://algate.github.io"},"pages":[],"posts":[{"title":"前端知识-小程序使用canvas画七巧板","slug":"微信小程序-画七巧板","date":"2020-07-26T02:38:30.000Z","updated":"2020-07-29T06:14:05.344Z","comments":true,"path":"archives/JS200726.html","link":"","permalink":"http://algate.github.io/archives/JS200726.html","excerpt":"","text":"每周的工作状态黄·历 - almanac综合运势:★ ★ ★ ★ ★爱情运势:★ ★ ★ ★ ★财富运势:★ ★ ★ ★ ★事业学业:★ ★ ★ ★ ★准备事项开发工具:uni-app,一套代码编到10个平台;开发环境:HBuilder,Vue,Node;部署环境:微信小程序;如下图所示:画七巧板的点位值:按照七巧板的图,把七巧板的每个色块按照{x,y}的对象方式存储在一个数组里。有七个色块,数组就有七个值:每个数组按照比例存储四块的每个点的位置信息;每个色块再加个颜色值,这个颜色随自己喜好添加。123456789tangram: [ { p: [{ x: 0, y: 0 }, { x: 800, y: 0 }, { x: 400, y: 400 }], color: '#caff67' }, { p: [{ x: 0, y: 0 }, { x: 400, y: 400 }, { x: 0, y: 800 }], color: '#67bccf' }, { p: [{ x: 800, y: 0 }, { x: 800, y: 400 }, { x: 600, y: 600 }, { x: 600, y: 200 }], color: '#cf3d61' }, { p: [{ x: 600, y: 200 }, { x: 600, y: 600 }, { x: 400, y: 400 }], color: '#f9f51a' }, { p: [{ x: 400, y: 400 }, { x: 600, y: 600 }, { x: 400, y: 800 }, { x: 200, y: 600 }], color: '#a594c0' }, { p: [{ x: 200, y: 600 }, { x: 400, y: 800 }, { x: 0, y: 800 }], color: '#fa8ccc' }, { p: [{ x: 800, y: 400 }, { x: 800, y: 800 }, { x: 400, y: 800 }], color: '#f6ca29' }]画七巧板正常浏览器页面写canvas:12var canvas=document.getElementById(\"canvas\");var context=canvas.getContext(\"2d\");基于uni-app实现小程序,这样是获取不到的。☺html添加canvas元素:HTML页面写canvas:123<template> <view><canvas style=\"width: 100vw;height: 100vw;\" type=\"2d\" canvas-id=\"tangram\" id=\"tangram\"></canvas></view></template>1.上述vue的html代码编译为h5:1234<uni-canvas data-v-2fdafd79=\"\" canvas-id=\"tangram\" type=\"2d\" id=\"tangram\" style=\"width: 100vw; height: 100vw;\"> <canvas width=\"393\" height=\"393\" style=\"height: 393px; width: 393px;\"></canvas> <div style=\"position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; overflow: hidden;\"></div></uni-canvas>2.编译为小程序为:1<canvas canvas-id=\"tangram\" id=\"tangram\" style=\"width: 100vw;height: 100vw;\" type=\"2d\"></canvas>获取canvas元素:H5获取canvas元素:12this.canvas = document.querySelector('#tangram canvas');this.ctx = this.canvas.getContext('2d');小程序获取canvas元素:12345678const query = uni.createSelectorQuery();query .select('#tangram') .fields({ node: true, size: true }) .exec(res => { this.canvas = res[0].node; this.ctx = this.canvas.getContext('2d'); }由于不同手机的分辨率和宽度像素不确定,还有手机的像素密度值。我们还需要调整七巧板点位置的相对比例(这个下边会有相关代码):此处我们按照整个屏幕来调整,首先先获取手机相关信息,除此之外手机还有一个像素密度值pixelRatio:123456uni.getSystemInfo({ success: res => { this.systemInfo = res; console.log(res); }})获取系统信息:12345678910111213errMsg: \"getSystemInfo:ok\"language: \"zh-CN\"model: \"iPhone\"pixelRatio: 2platform: \"ios\"screenHeight: 667screenWidth: 375statusBarHeight: 0system: \"iOS 13.2.3\"windowBottom: 0windowHeight: 623windowTop: 44windowWidth: 375根据系统和屏幕信息给canvas设置width和height:给canvas设置width和height:h5设置为:123const dpr = uni.getSystemInfoSync().pixelRatio;this.canvas.width = this.systemInfo.windowWidth * dpr;this.canvas.height = this.systemInfo.windowWidth * dpr;小程序设置为:123const dpr = uni.getSystemInfoSync().pixelRatio;this.canvas.width = res[0].width * dpr;this.canvas.height = res[0].width * dpr;由于手机端有pixelRatio像素密度,真实的手机端需要canvas缩放,负责显示为半个canvas,所以在小程序端需要添加(h5端添加显示错乱):1this.ctx.scale(dpr, dpr);用canvas画七巧板:七巧板点位置的数字:【0,200,400,600,800】如果不调整,不是全屏展示整个七巧板,可以按照最小手机的分辨率相对按比例缩小;如果要全屏展示七巧板,我们需要获取屏幕的宽度,然后按照比例进行缩放上述点位置;获取到canvas,然后接下来就是画七巧板。我们吧这个方法提出来直接写个方法,获取到canvas,执行this.draw();画之前,先按照比例缩放七巧板点位置的比例:12345678910111213141516171819202122232425this.tangram.map(plece => { return plece.p.map(coordinate => { if (coordinate.x === 200) { coordinate.x = this.systemInfo.windowWidth / 4; } else if (coordinate.x === 400) { coordinate.x = this.systemInfo.windowWidth / 2; } else if (coordinate.x === 600) { coordinate.x = (this.systemInfo.windowWidth / 4) * 3; } else if (coordinate.x === 800) { coordinate.x = this.systemInfo.windowWidth; } if (coordinate.y === 200) { coordinate.y = this.systemInfo.windowWidth / 4; } else if (coordinate.y === 400) { coordinate.y = this.systemInfo.windowWidth / 2; } else if (coordinate.y === 600) { coordinate.y = (this.systemInfo.windowWidth / 4) * 3; } else if (coordinate.y === 800) { coordinate.y = this.systemInfo.windowWidth; } });});for (var i = 0; i < this.tangram.length; i++) { this.draw(this.tangram[i], ctx);}draw()方法:12345678910draw(plece, cxt) { cxt.beginPath(); cxt.moveTo(plece.p[0].x, plece.p[0].y); for (var i = 1; i < plece.p.length; i++) { cxt.lineTo(plece.p[i].x, plece.p[i].y); } cxt.closePath(); cxt.fillStyle = plece.color; cxt.fill();}画七巧板代码中使用this,需要data里边定义变量:1234systemInfo: {},canvas: null,ctx: null,tangram: []完结,如果想体验直接扫码访问小程序,进入首页,点击体验或者授权都可以,菜单canvas下,点击Tangram.js,就可以浏览七巧板效果;体验地址小程序码:h5访问地址:h5展示-浏览器打开手机浏览模式F12公众号访问:","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"小程序","slug":"小程序","permalink":"http://algate.github.io/tags/小程序/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"承认别人的牛逼才是真正的牛逼","slug":"心态-保持一颗平常心","date":"2020-03-26T12:19:00.000Z","updated":"2020-03-26T09:33:56.095Z","comments":true,"path":"archives/54500.html","link":"","permalink":"http://algate.github.io/archives/54500.html","excerpt":"","text":"这世间有一种恶,叫见不得你好。你有没有发现,越是无能的人,越是不愿意承认别人的能力。但其实,承认别人的牛逼,才是真正的牛逼。这世间有一种恶,叫见不得你好。尤其是在当下互联网生态下,隔着屏幕“越是得不到,越是要攻击。”当财富蜂拥入驻到一个极其平凡人的身上时,周围人则会想尽办法将一切晦暗的思想嫁接在他身上。也将这个社会的戾气,越引越爆。在这些眼里,别人的优秀都是假的。仿佛是给屌丝们给自己找了个借口:“这世上根本就没有人真正做到优秀,所以我做不到也很正常。”一副见不得别人好的丑恶嘴脸。古人说富贵当思原由,不是无道理。人活在世,不要老问凭什么,要多问为什么?想想什么网红这么多,只有李佳琦和李子柒能够脱颖而出。好好思考一下,为什么条条道路通罗马,而你活在非洲。为什么成功的那个人不是你?为什么加薪的那个人不是你?不思考不反省,思维也就越发贫穷,穷则生戾。如此循环…我们都听过这么一句话:“比你优秀的人,比你更努力。”而不努力的你,正在掉进“贫困陷井”中。换句话说,久而久之,穷不仅仅是没钱这么简单,而是思维上的贫穷。穷人缺什么?表面缺资金,本质缺野心,脑子缺观念,机会缺了解,骨子缺勇气,改变缺行动,事业缺毅力。影视剧《新上海滩》中有这样一个镜头,阅历丰厚的冯敬尧问年轻气盛的丁力:“穷人最缺的是什么?”丁力回答:“穷人最缺的当然是钱。”冯敬尧摇摇头说:“是野心。”“老天安排你是个穷人,你若认命你就会穷一辈子,若不认命就得有改变的野心。”没有了改变的野心,自然就没有勇气,又谈何毅力?这背后是一个个“穷人”逆袭,不认命的故事。而这些酸他们的人,不过一群躲在屏幕后面loser。人穷不可怕,心穷才是真正的可悲。“长得好看,肯定是整的。”“嫁得好,肯定是为了钱。”“升职加薪,肯定是背后有关系。”你有没有发现,越是无能的人,越是不愿意承认别人的能力。但其实,承认别人的牛逼,才是真正的牛逼。","categories":[{"name":"日记","slug":"日记","permalink":"http://algate.github.io/categories/日记/"}],"tags":[{"name":"心态","slug":"心态","permalink":"http://algate.github.io/tags/心态/"}],"keywords":[{"name":"日记","slug":"日记","permalink":"http://algate.github.io/categories/日记/"}]},{"title":"ES6下对象的解构赋值","slug":"ES6下对象的解构赋值","date":"2019-12-28T02:38:30.000Z","updated":"2020-01-02T08:18:00.531Z","comments":true,"path":"archives/JS191228.html","link":"","permalink":"http://algate.github.io/archives/JS191228.html","excerpt":"","text":"对象的解构赋值对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。先看个例子:123456let { bar, foo } = { foo: \"aaa\", bar: \"bbb\" };foo // \"aaa\"bar // \"bbb\"let { baz } = { foo: \"aaa\", bar: \"bbb\" };baz // undefined那么再来看个123let { foo: baz } = { foo: \"aaa\", bar: \"bbb\" };baz // \"aaa\"foo // error: foo is not definedfoo为啥会报错呢?大家需要首先记住的是:对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。12345678910let obj = { p: [ 'Hello', { y: 'World' } ]};let { p: [x, { y }] } = obj;x // \"Hello\"y // \"World\"大家猜猜 打印p的话,会是什么结果呢?显而易见,大家自己打印看看。注意,p是模式,不是变量。偏要赋值就要变成变量:1let { p, p: [x, { y }] } = obj;我们看看复杂一点的例子:1234567891011121314const node = { loc: { start: { line: 1, column: 5 } }};let { loc, loc: { start }, loc: { start: { line }} } = node;line // 1collumn // ??loc // ??start // ??大家说说结果:对了就可以说明你的掌握模式和变量的区别了。解释:上面代码有三次解构赋值,分别是对loc、start、line三个属性的解构赋值。注意,最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量。(概括的说:冒号左边的都是模式,没有冒号或者冒号右边的是变量)对象的解构也可以指定默认值。123456789101112131415var {x = 3} = {};x // 3var {x, y = 5} = {x: 1};x // 1y // 5var {x: y = 3} = {};y // 3var {x: y = 3} = {x: 5};y // 5var { message: msg = 'Something went wrong' } = {};msg // \"Something went wrong\"还有一个需要注意的是:默认值生效的条件是,对象的属性值严格等于undefined。12345var {x = 3} = {x: undefined};x // 3var {x = 3} = {x: null};x // null最重要的对象解构赋值就是这些。完……","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"ES6","slug":"ES6","permalink":"http://algate.github.io/tags/ES6/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"Powershell使用命令","slug":"计算机-Powershell使用命令","date":"2019-12-26T04:09:30.000Z","updated":"2019-12-25T06:05:25.620Z","comments":true,"path":"archives/JS191226.html","link":"","permalink":"http://algate.github.io/archives/JS191226.html","excerpt":"","text":"1 PS工具常用命令集合:1.1 在当前文件夹下打开PS:按住Shift 右击鼠标选择在此处打开Powershell窗口1.2 PS中打开当前文件夹有时候,开着PS可是呢,要打开当前资源管理器,对文件进行处理,目录太深,如何快捷打开当前文件夹有了PS当然是通过命令来处理了:1start .这是最简单的,当然还有别的方法:explorer(gl) 如果不输入(gl)则是打开计算机(Win+E)……别的不写了,太复杂了,有一个就够用了1.3 PS中新建文件/文件夹12新建文件New-Item file (只能新建文件)12新建文件夹md/mkdir filefolder (只能新建文件夹)12新建文件/文件夹New-Item filefolder -type File/Directory1.4 PS中删除文件和文件夹1Remove-Item file/filefolder1ri/rd/rm/rmdir/erase file/filefolder1.5 打开cmd1start cmd1.6 资源管理器打开文件夹1start foldermd 为mkdir的缩写1.5 PS查看文件内容1get-content file (后缀也得加上)1.6 PS清空命令行1cls1.7 PS目录查找12cd.. (返回上级菜单)cd filefloder (访问目录问价夹)","categories":[{"name":"计算机","slug":"计算机","permalink":"http://algate.github.io/categories/计算机/"}],"tags":[{"name":"计算机","slug":"计算机","permalink":"http://algate.github.io/tags/计算机/"},{"name":"Powershell","slug":"Powershell","permalink":"http://algate.github.io/tags/Powershell/"}],"keywords":[{"name":"计算机","slug":"计算机","permalink":"http://algate.github.io/categories/计算机/"}]},{"title":"删除系统找不到的文件","slug":"计算机-系统找不到文件如何删除","date":"2019-12-25T14:37:30.000Z","updated":"2019-12-25T02:52:14.812Z","comments":true,"path":"archives/JS191225.html","link":"","permalink":"http://algate.github.io/archives/JS191225.html","excerpt":"","text":"删除文件时提示“找不到该项目”,怎么解决?经过三番五次的尝试,发现都不行,你是不是想重启电脑试试!现在有个很简单的方法,试了一下,果然好用,推荐个大家1.新建一个文件名字为啥无所谓1New-Item del.bat2.打开文件输入以下运行命令12DEL /F /A /Q \\\\?\\%1RD /S /Q \\\\?\\%13.删除文件把系统不存在的文件或者文件夹拖到该bat文件上。你就会发现神奇的事情!","categories":[{"name":"计算机","slug":"计算机","permalink":"http://algate.github.io/categories/计算机/"}],"tags":[{"name":"计算机","slug":"计算机","permalink":"http://algate.github.io/tags/计算机/"},{"name":"技术支持","slug":"技术支持","permalink":"http://algate.github.io/tags/技术支持/"}],"keywords":[{"name":"计算机","slug":"计算机","permalink":"http://algate.github.io/categories/计算机/"}]},{"title":"JavaScript-Array迭代器方法","slug":"JavaScript-Array迭代器方法","date":"2019-12-24T08:49:30.000Z","updated":"2020-05-29T07:17:39.751Z","comments":true,"path":"archives/JS191224.html","link":"","permalink":"http://algate.github.io/archives/JS191224.html","excerpt":"【1】 第一组迭代器方法不产生任何新数组,要么对于数组中的每个元素执行某种操作,要么返回一个值;1.forEach() 接受一个函数作为参数,对数组中的每个元素使用该函数123456789function square(num) { print(num, num * num);}var nums = [];for (var i = 0; i < 10; ++i) { nums[i] = i+1;}nums.forEach(square);","text":"【1】 第一组迭代器方法不产生任何新数组,要么对于数组中的每个元素执行某种操作,要么返回一个值;1.forEach() 接受一个函数作为参数,对数组中的每个元素使用该函数123456789function square(num) { print(num, num * num);}var nums = [];for (var i = 0; i < 10; ++i) { nums[i] = i+1;}nums.forEach(square);2.every() 接受一个返回值为布尔类型的函数,对数组中的每个元素使用该函数。对于所有的元素,该函数返回true,则该方法返回true123456789101112function isEven(num) { return num % 2 == 0;}var nums = [2,4,6,8,10];var even = nums.every(isEven);if (even) { print(\"all numbers are even\");}else { print(\"some numbers are odd\");}some() 方法也接受一个返回值为布尔类型的函数,只要有一个元素使得该函数返回true,该方法就返回true。1234567891011121314151617181920function isEven(num) { return num % 2 == 0;}var nums = [1,2,3,4,5,6,7,8,9,10];var someEven = nums.some(isEven);if (someEven) { print(\"some numbers are even\");}else { print(\"no numbers are even\");}nums = [1,3,5,7,9];var someEven = nums.some(isEven);if (someEven) { print(\"some numbers are even\");}else { print(\"no numbers are even\");}3.reduce() 接受一个函数,返回一个值。 它会从一个累加值开始,不断对累加值和数组中的后续元素调用该函数,最后返回累加值。也可以用来将数组中的元素连接成一个长字符串reduceRight() 与 reduce()类似,是从右往左执行。【2】 生成新数组的迭代器方法1.map() 和forEach()有点儿像,对数组中的每个元素使用某个函数。区别就是,map()返回一个新的数组,该数组的元素是对原有元素应用某个函数得到的结果。123456function curve(grade) { retuan grade += 5;}var grades = [77, 65, 81, 92, 83];var newgrades = grade.map(curve);print(newgrades);2.filter() 和every类似,传入一个返回值为布尔类型的函数。和every()和some()不同的是,当对数组中的所有元素应用该函数,返回结果均为true时,该方法并不返回true,而是返回一个新的数组,该数组只包含原数组元素应用该函数后返回结果为true的元素。123456789101112131415161718function isEven(num) { return num % 2 == 0;}function isOdd(num) { return num % 2 != 0;}var nums = [];for (var i = 0; i < 20; ++i) { nums[i] = i+1;}var evens = nums.filter(isEven);print(\"Even numbers: \");print(evens);var odds = nums.filter(isOdd);print(\"Odd numbers: \");print(odds);","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"JavaScript","slug":"JavaScript","permalink":"http://algate.github.io/tags/JavaScript/"},{"name":"数据结构与算法","slug":"数据结构与算法","permalink":"http://algate.github.io/tags/数据结构与算法/"},{"name":"迭代器方法","slug":"迭代器方法","permalink":"http://algate.github.io/tags/迭代器方法/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"我借用了别人的小程序","slug":"我借用了别人的小程序","date":"2019-10-17T02:38:30.000Z","updated":"2019-10-18T08:40:23.091Z","comments":true,"path":"archives/JS191017.html","link":"","permalink":"http://algate.github.io/archives/JS191017.html","excerpt":"","text":"如何发布小程序?我要开始写我自己的UniAppUI组件了。敬请期待……","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"小程序","slug":"小程序","permalink":"http://algate.github.io/tags/小程序/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"微信公众号Django-内网穿透-服务器配置-python环境-token验证.md","slug":"微信公众号Django-内网穿透-服务器配置-python环境-token验证","date":"2019-08-31T04:44:30.000Z","updated":"2019-08-31T08:49:38.408Z","comments":true,"path":"archives/JS190831.html","link":"","permalink":"http://algate.github.io/archives/JS190831.html","excerpt":"","text":"说明: 微信公众号文档,以及python,好友后续的内容涉及的相关知识,都在python2.7版本下进行的测试验证python3.0+版本出现各种问题,so,以下内容都在python2.7的环境下有效,先安装python2.71.微信公众号开发者文档服务器配置1-1.搭建服务(Python Web服务)开发者文档这里就用Django搭建服务了,方便省事(不用自己写代码了)2.搭建Django(Python Web 框架)2.1 安装DjangoDjango官方直接看 如何在Windows上安装Django?[1]pip install Django(推荐 pip为python的安装工具也可以使用easy_install django来进行安装)2.2 创建your first Django apphttps://docs.djangoproject.com/en/2.2/intro/tutorial01/django-admin startproject mysite mysite为你要创建的web站文件夹 我的为 DjangoWechat创建完之后,文件夹下会有一个文件夹,cd之后,里边还有个一相同的文件夹名mysite/ manage.py mysite/ __init__.py settings.py urls.py wsgi.py 2.3 启动服务py manage.py runserver 8080打开浏览器就可以看到成功的默认页面2.4 部署自己的app项目首先创建一个存放你项目的apppython manage.py startapp polls 我的是wechatpolls/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py Django默认是吧页面放到templates下的,资源是放在static下的一般打包的项目index.html加一个static文件夹,so 复制你的项目到polls下,把index.html放到templates下即可,不需要修改你项目里的路径2.5 访问服务下的index.html2.5.1 修改Djangon项目下urls.py# 导入app from polls(wechat) import views # add url(r'^$', views.home, name='home'), 2.5.2 修改polls(wechat)下views.py# from django.shortcuts import render from django.shortcuts import render, render_to_response, HttpResponse def home(request): return render_to_response('index.html') 现在应该可以看到index.html效果展示了3.微信服务器配置token验证3.1 公众号登录 - 基础配置 - 服务器配置服务器地址(URL) : http://此处可以通过内网穿透来实现自己的域名/weixin/(weixin这个自己定义,需要和Django下的定义的接口一致就行)令牌(Token):设置自己的我是起的项目名CloudUI消息加解密密钥(EncodingAESKey):点击按钮自动生成3.2 点击提交,你会发现报错token验证失败 - 只是最多的提示,就是微信发送请求,没哟得到正确的结果请求超时,说明服务没起4.Django服务添加验证接口4.1 修改Django项目下的urls.py4.1.1修改Djangon项目下urls.py# 添加接口(views为之前修改首页导入的app的入口模块,wechat为定义的app下的访问的模块方法) url(r'weixin/.*', views.wechat), 4.1.2 修改polls(wechat)下views.py# add wechat-token from django.views.decorators.csrf import csrf_exempt # 解除csrf验证 from wechat_sdk import WechatConf from wechat_sdk import WechatBasic ## add wechat-token conf = WechatConf( # 实例化配置信息对象 token='', # 服务器配置-Token appid='', # 公众号开发信息-开发者ID appsecret='', # 公众号开发信息-开发者密码 encrypt_mode='normal', # 服务器配置-明文模式 encoding_aes_key='' # 服务器配置-EncodingAESKey ) @csrf_exempt # 去除csrf验证 def wechat(request): signature = request.GET.get('signature') # 获取请求信息 timestamp = request.GET.get('timestamp') nonce = request.GET.get('nonce') wechat_instance = WechatBasic(conf=conf) # 实例化微信基类对象 if not wechat_instance.check_signature(signature=signature, timestamp=timestamp, nonce=nonce): # 检查验证请求的签名 return HttpResponseBadRequest('Verify Failed') else: if request.method == 'GET': return HttpResponse(request.GET.get('echostr', None)) # 返回请求中的回复信息 4.2 安装wechat-sdkpip install wechat-sdk此处服务如果报错 |_4.3 Unable to find vcvarsall.bat(有可能是找不到模块导致的)(安装python的时候可能报错 - 此处如果报错跟这个可能关系不大 - 往上翻)报错往上翻,不是文档往上翻Unable to find vcvarsall.bat4.4 安装Crypto官方验证有个Python实例(用于验证的):目录: E:\\JavascriptCode\\webPy\\微信公众号\\SampleCode\\Python Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2017/7/27 20:40 795 ierror.py -a---- 2017/7/27 20:40 2372 Sample.py -a---- 2017/7/27 20:40 9400 WXBizMsgCrypt.py -a---- 2017/7/27 20:40 0 __init__.py 如果用到WXBizMsgCrypt.py,在windows会报错from Crypto.Cipher import AES ImportError: No module named ‘Crypto’可以直接pip install Crypto 如果成功,直接看第五步,如果不成功就接着看。里边有这么一段:“””关于Crypto.Cipher模块,ImportError: No module named ‘Crypto’解决方案请到官方网站 https://www.dlitz.net/software/pycrypto/ 下载pycrypto。下载后,按照README中的“Installation”小节的提示进行pycrypto安装。“””下载pycrypto-2.6.1.tar.gz文件接4.44.5 解压pycrypto下找到readme文件的Installation执行 python setup.py install会发现报错Unable to find vcvarsall.bat(此处关系不大,否则python安装会提示)先验证vb,vc是否安装?Unable to find vcvarsall.bat如果还是报错Python安装目录\\Lib\\site-packages下是否有Crypto如果有,保证首字母大写如果没有,copy一份放进去。重新执行 py setup.py install(pip install Crypto)即可,只要最后出现successing的字样就表示你成功了!5.内网穿透5.1 网上随便找一个就ok,只要能外网访问到项目就okDjango 与 设置的外网访问的 端口号要保持一致127.0.0.1带上微信请求的接口自己本地先测试下。是否ok,欧克的话就可以公众号验证token了。此处需要把127.0.0.1 /内网穿透的域名 配置到Django环境下settings.py的ALLOWED_HOSTS = []里如果不成功那就看看报错出在哪里。慢慢解决此处的域名访问填写到微信公众号的服务器配置里分别填写token,密钥然后提交,就会发现token验证成功了,如果报错,请上翻查找原因","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"微信公众号","slug":"微信公众号","permalink":"http://algate.github.io/tags/微信公众号/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"内网穿透工具","slug":"全栈-内网穿透工具","date":"2019-08-29T03:20:30.000Z","updated":"2019-12-25T06:31:34.383Z","comments":true,"path":"archives/JS190829.html","link":"","permalink":"http://algate.github.io/archives/JS190829.html","excerpt":"","text":"1.内网穿透工具1-1.ngrok1-2.Natapp1-3.localtunnel安装localtunnelnpm install -g localtunnel开启localtunnel服务1)指定的端口号 –port 8000 必须与 localhost的8000相对应2)–subdomain mitu : 指定前缀为 mitu3) lt 为localtunnel 缩写4. 最后, 在外网浏览器输入 https://mitu.localtunnel.me 即可访问本地的localhost:8000, 需要注意的是,localtunnel的服务器是国外,有时候访问可能不太理想1-4.uTools:1-5.open-dingtalk/pierced地址cmd下运行命令http://u.tools/其他参考地址前5个都是基于国外的ngrok来进行二次开发的。1、Ngrokngrok 是一个反向代理,通过在公共端点和本地运行的 Web 服务器之间建立一个安全的通道,实现内网主机的服务可以暴露给外网。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放,所以ngrok可以很方便地协助服务端程序测试。参考博客:10分钟教你搭建自己的ngrok服务器2、Natappnatapp是 基于ngrok的国内收费内网穿透工具,类似花生壳,有免费版本,比花生壳好。免费版本:提供http,https,tcp全隧道穿透,随机域名/TCP端口,不定时强制更换域名/端口,自定义本地端口参考文章:NATAPP1分钟快速新手图文教程3、小米球小米球是基于ngrok二次开发的内网穿透工具,支持多协议、多隧道、多端口同时映射(http、https、tcp等等…),同时支持多种系统win、linux、linux_arm、mac等。具体的使用直接参考官网。4、Sunny-NgrokSunny-Ngrok同样是ngrok二次开发的内网穿透工具,支持http,https协议,同时支持更丰富的系统和语言:linux、win、mac、openwrt、 python、php等。教程:Sunny-Ngrok使用教程5、echositeechosite同样ngrok二次开发的内网穿透工具,支持多种协议,以前是全部免费的,现在推出了收费版和免费版,可根据自己的需要去选择。参考教程:EchoSite—让内网穿透变得简单6、Ssh、autosshssh 配合autossh工具使用,因为autossh会容错,自动重新启动SSH会话和隧道。autossh是一个程序,用于启动ssh的副本并进行监控,在死亡或停止传输流量时根据需要重新启动它。 这个想法来自rstunnel(Reliable SSH Tunnel),但是在C中实现。作者的观点是,它不像匆匆忙忙的工作那么容易。使用端口转发环路或远程回显服务进行连接监视。在遇到连接拒绝等快速故障时,关闭连接尝试的速度。在OpenBSD,Linux,Solaris,Mac OS X,Cygwin和AIX上编译和测试; 应该在其他BSD上工作。免费软件。使用教程:SSH内网穿透7、Lanproxylanproxy是一个将局域网个人电脑、服务器代理到公网的内网穿透工具,目前仅支持tcp流量转发,可支持任何tcp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面…)。目前市面上提供类似服务的有花生壳、TeamView、GoToMyCloud等等,但要使用第三方的公网服务器就必须为第三方付费,并且这些服务都有各种各样的限制,此外,由于数据包会流经第三方,因此对数据安全也是一大隐患。参考教程:业余草推荐一款局域网(内网)穿透工具lanproxy8、SpikeSpike是一个可以用来将你的内网服务暴露在公网的快速的反向代理,基于ReactPHP,采用IO多路复用模型。采用Php实现。参考教程:使用 PHP 实现的的内网穿透工具 “Spike”9、Frpfrp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议。利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服务。对于 http, https 服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个80端口。利用处于内网或防火墙后的机器,对外网环境提供 tcp 和 udp 服务,例如在家里通过 ssh 访问处于公司内网环境内的主机。教程:一款很好用的内网穿透工具–FRP、使用frp实现内网穿透10、FcnFCN[free connect]是一款傻瓜式的一键接入私有网络的工具, fcn利用公共服务器以及数据加密技术实现:在免公网IP环境下,在任意联网机器上透明接入服务端所在局域网网段。支持多种系统,有免费版和付费版","categories":[{"name":"工具","slug":"工具","permalink":"http://algate.github.io/categories/工具/"}],"tags":[{"name":"前端工具","slug":"前端工具","permalink":"http://algate.github.io/tags/前端工具/"}],"keywords":[{"name":"工具","slug":"工具","permalink":"http://algate.github.io/categories/工具/"}]},{"title":"JavaScript好用的Web-Api","slug":"JavaScript好用的Web-Api","date":"2019-08-26T02:57:30.000Z","updated":"2019-09-06T03:50:29.600Z","comments":true,"path":"archives/JS190826.html","link":"","permalink":"http://algate.github.io/archives/JS190826.html","excerpt":"","text":"1.closest(元素向上查询)closest跟querySelector相反,该元素可以向上查询,也就是可以查询到父元素:document.querySelector(“li”).closest(“#nav”);2.dataset(获取元素以”data-“为前缀的属性集合)dataset就跟原生微信小程序一样,能获取标签上以”data-“为前缀的属性集合:document.querySelector(“p”).dataset; // {name: “蜘蛛侠”, age: “16”}注意:虽然可以用getAttribute方法获取任何属性值,但是性质却不一样,这是开发规范问题,凡是自定义属性都要加上data-前缀哦3.URLSearchParams(查询参数)URLSearchParams假设浏览器的url参数是 “?name=蜘蛛侠&age=16”:1new URLSearchParams(location.search).get(\"name\"); // 蜘蛛侠4.hidden(隐藏元素)这是一个html属性,规定元素是否隐藏,表现跟css的display: none一致:<div hidden>我被隐藏了</div>document.querySelector("div").hidden = true / false;5.classList(类名控制器)classList这是一个对象,该对象里封装了许多操作元素类名的方法:<p class="title"></p>1234567891011let elem = document.querySelector(\"p\");// 增加类名elem.classList.add(\"title-new\"); // \"title title-new\"// 删除类名elem.classList.remove(\"title\"); // \"title-new\"// 切换类名(有则删、无则增,常用于一些切换操作,如显示/隐藏)elem.classList.toggle(\"title\"); // \"title-new title\"// 替换类名elem.classList.replace(\"title\", \"title-old\"); // \"title-new title-old\"// 是否包含指定类名elem.classList.contains(\"title\"); // false6.contains(判断是否包含指定元素)contains可以判断指定元素是否包含了指定的子元素:1234<div> <p></p></div>document.querySelector(\"div\").contains(document.querySelector(\"p\")); // true7.online state(网络状态)online state监听当前的网络状态变动,然后执行对应的方法:12345window.addEventListener(\"online\", xxx);window.addEventListener(\"offline\", () => { alert(\"你断网啦!\");});使用场景:提示用户已断网,直接一个弹框把用户吓懵8.battery state(电池状态)battery state获取设备的电池状态:12345678910111213navigator.getBattery().then(battery => console.log(battery));// 返回{ charging, // 是否在充电 chargingTime, // 充满电所需时间 dischargingTime, // 当前电量可使用时间 level, 剩余电量 onchargingchange, // 监听充电状态变化 onchargingtimechange, // 监听充满电所需时间变化 ondischargingtimechange, // 监听当前电量可使用时间变化 onlevelchange // 监听电量变化}使用场景:提示用户电量已充满,或者为了让用户有安全感,电量低于99%的时候来个弹框提示”该充电啦”9.vibration(设备震动)嘻嘻,使设备进行震动:// 震动一次navigator.vibrate(100);// 连续震动,震动200ms、暂停100ms、震动300msnavigator.vibrate([200, 100, 300]);效果如下:不好意思你得用你自己的手握住手机才能感受得到;使用场景:通过振动来提供感官反馈,比如太久没有触摸屏幕的时候连续震动提醒用户10.page visibility(页面可见性)顾名思义,这个API是用来监听页面可见性变化的,在PC端标签栏切换、最小化会触发、在移动端程序切到后台会触发,简单说就是页面消失了🤦♂️123document.addEventListener(\"visibilitychange\", () => { console.log(`页面可见性:${document.visibilityState}`);});PC端效果如下:移动端效果如下:使用场景:当程序切到后台的时候,如果当前有视频播放或者一些动画执行,可以先暂停11.deviceOrientation(陀螺仪)deviceOrientation陀螺仪,也就是设备的方向,又名重力感应,该API在IOS设备上失效的解决办法,将域名协议改成https;从左到右分别为alpha、beta、gamma:1234567891011window.addEventListener(\"deviceorientation\", event => { let { alpha, beta, gamma } = event; console.log(`alpha:${alpha}`); console.log(`beta:${beta}`); console.log(`gamma:${gamma}`);});使用场景:页面上的某些元素需要根据手机摆动进行移动,达到视差的效果,比如王者荣耀进入游戏的那个界面,手机转动背景图会跟着动12.toDataUrl(画布内容转base64)toDataURL这个canvas的API,作用是将画布的内容转换成一个base64的图片地址:1234let canvas = document.querySelector(\"canvas\");let context = canvas.getContext(\"2d\");//……let url = canvas.toDataURL(\"image/png\"); // 将画布内容转换成base64地址使用a标签进行图片下载时,图片链接跨域(图片是我的掘金头像),无法进行下载而是进行图片预览:1234<img src=\"xxx\"><button> <a href=\"xxx\" download=\"avatar\">下载图片</a></button>封装以下代码便可解决✅12345678910111213141516171819202122232425const downloadImage = (url, name) => { // 实例化画布 let canvas = document.createElement(\"canvas\"); let context = canvas.getContext(\"2d\"); // 实例化一个图片对象 let image = new Image(); image.crossOrigin = \"Anonymous\"; image.src = url; // 当图片加载完毕 image.onload = () => { // 将图片画在画布上 canvas.height = image.height; canvas.width = image.width; context.drawImage(image, 0, 0); // 将画布的内容转换成base64地址 let dataURL = canvas.toDataURL(\"image/png\"); // 创建a标签模拟点击进行下载 let a = document.createElement(\"a\"); a.hidden = true; a.href = dataURL; a.download = name; document.body.appendChild(a); a.click(); }}或者将当前的DOM转换成图片进行下载,常用于生成海报,推荐插件html2canvas,大家可以自己去搜;13.customEvent(自定义事件)customEvent自定义事件,就跟vue里面的on跟emit一样;监听自定义事件:123456789window.addEventListener(\"follow\", event => { console.log(event.detail); // 输出 {name: \"前端宇宙情报局\"}});派发自定义事件:window.dispatchEvent(new CustomEvent(\"follow\", { detail: { name: \"前端宇宙情报局\" }}));14.notification(桌面通知)notificationPC端的桌面通知,如网页端的微信,当收到消息时,右下角会出现一个通知(尽管你把浏览器最小化),因为这个通知时独立于浏览器的,是系统的一个原生控件:1234567891011const notice = new Notification(\"前端宇宙情报局\", { body: \"这20个不常用的Web API真的有用吗?,别问,问就是有用🈶\", icon: \"我的掘金头像\", data: { url: \"https://www.baidu.com\" }});// 点击回调notice.onclick = () => { window.open(notice.data.url); // 当用户点击通知时,在浏览器打开百度网站}效果如下:注意:想要成功的调起通知,首先要用户的授权✅Notification.requestPermission(prem => {prem == “granted” // 同意prem == “denied” // 拒绝})所以,再调用之前先向用户发起请求:12345678910let permission = Notification.permission;if (permission == \"granted\") { // 已同意,开始发送通知 ...} else if (permission == \"denied\") { // 不同意,发不了咯} else { // 其他状态,可以重新发送授权提示 Notification.requestPermission();}15.fullScreen(全屏)fullScreen全屏不咯? 之前的一个项目刚好用上,不仅仅可以作用在documentElement上,还可以作用在指定元素:12345678910111213/** * @method launchFullScreen 开启全屏 * @param {Object} elem = document.documentElement 作用的元素 */const launchFullScreen = (elem = document.documentElement) => { if(elem.requestFullScreen) { elem.requestFullScreen(); } else if(elem.mozRequestFullScreen) { elem.mozRequestFullScreen(); } else if(elem.webkitRequestFullScreen) { elem.webkitRequestFullScreen(); }}作用在documentElement上没啥可以介绍的咯,就相当于F11开启全屏:那么作用在指定元素会是什么效果呢?就像效果图一样,会直接开启全屏,并且只显示指定的元素,元素的宽高填充了整个屏幕✅关闭全屏的时候需要注意的是,统一用document对象:123456789101112/** * @method exitFullScreen 关闭全屏 */const exitFullScreen = () => { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitCancelFullScreen) { document.webkitCancelFullScreen(); }}使用场景:需要让用户专注去做某件事,比如代码编辑区的全屏16.orientation(屏幕方向)orientation可以监听用户手机设备的旋转方向变化:123window.addEventListener(\"orientationchange\", () => { document.body.innerHTML += `<p>屏幕旋转后的角度值:${window.orientation}</p>`;}, false);效果如下:也可以使用css的媒体查询:123456789101112/* 竖屏时样式 */@media all and (orientation: portrait) { body::after { content: \"竖屏\" }}/* 横屏时样式 */@media all and (orientation: landscape) { body::after { content: \"横屏\" }}使用场景:页面需要用户开启横屏来获得更好的体验17.getBoundingClientRect(元素空间结构详细信息)getBoundingClientRect可以获取指定元素在当前页面的空间信息:123456789101112elem.getBoundingClientRect();// 返回{ x: 604.875, y: 1312, width: 701.625, height: 31, top: 1312, right: 1306.5, bottom: 1343, left: 604.875}注意:top是距离文档顶部的距离,y则是距离可视窗口(浏览器屏幕)的顶部距离,如果浏览器滚动,top值不变,y值会变· MDN Web API接口","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"JavaScript","slug":"JavaScript","permalink":"http://algate.github.io/tags/JavaScript/"},{"name":"WebApi","slug":"WebApi","permalink":"http://algate.github.io/tags/WebApi/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"JavaScript工具相关使用","slug":"JavaScript工具相关使用","date":"2019-04-26T02:38:30.000Z","updated":"2019-08-26T03:33:07.431Z","comments":true,"path":"archives/JS190426.html","link":"","permalink":"http://algate.github.io/archives/JS190426.html","excerpt":"","text":"1.serve不用express,不用部署http环境,可以直接运行编译后代码用法:serve -s ./docs -p 8888安装:node环境全局安装 serve 依赖 ( cnpm install -g serve )2.font-spider打包文件之后,可以压缩页面中引用的字体文件(字体图标除外)用法:font-spider ./html文件路径安装:cnpm install font-spider -g","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"JavaScript","slug":"JavaScript","permalink":"http://algate.github.io/tags/JavaScript/"},{"name":"打包工具","slug":"打包工具","permalink":"http://algate.github.io/tags/打包工具/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"睡前收入睡后收入第一节","slug":"理财-睡前收入睡后收入第一节","date":"2019-04-16T12:19:00.000Z","updated":"2019-12-25T02:37:57.289Z","comments":true,"path":"archives/54500.html","link":"","permalink":"http://algate.github.io/archives/54500.html","excerpt":"","text":"睡前收入,睡后收入。你能明白,你就实现了自由!一个人,只要不是含着金钥匙出生的,财富最初总是靠出售体力或智力劳动换来的,并在满足我们消费需求之后,通过配置在不同的资产上获取。套用一句流行语,或者是“睡前收入”,或者是“睡后收入”。所谓睡前收入,就是你干活就有、睡着了就没有的那种,使用自己的体力或者智力还钱。所谓睡后收入,就是被动性收入,哪怕你睡着了,它也在自动增值。两种收入形态中,很明显,睡后收入占比越高,你就有越多可供自由支配的时间,所做选择受到的制约也就越少。收入来源全部由睡后收入构成,就进入了所谓财务自由状态。受限于认知水平,我们最先接触到的睡后收入,可能都是银行存款,还是年回报率“高”达0.35%的活期存款,其后由于你多学习了一点点,你可能开始会搞阿里余额宝、腾讯理财通、甲银行B理财…… ,收益率开始从0.35%提升到3%~5%之间。这一步很容易实现,是因为这个回报率依然远在社会平均财富增长值之下,属于将自己辛辛苦苦卖体力或者脑力换来的财富,无偿地送给别人一部分。将财富从自己口袋里掏出来.","categories":[{"name":"日记","slug":"日记","permalink":"http://algate.github.io/categories/日记/"}],"tags":[{"name":"理财","slug":"理财","permalink":"http://algate.github.io/tags/理财/"}],"keywords":[{"name":"日记","slug":"日记","permalink":"http://algate.github.io/categories/日记/"}]},{"title":"Node好用的工具集绵","slug":"node好用的工具-集绵","date":"2019-03-09T07:23:01.000Z","updated":"2019-12-24T08:11:20.496Z","comments":true,"path":"archives/201903091523.html","link":"","permalink":"http://algate.github.io/archives/201903091523.html","excerpt":"","text":"No.1 servecnpm install -g serve写博客发布后、项目打包要上线…… 你要花一分钟预览下,index.html启动的文件是否可以正产使用之前,我一直使用node+http-server+express 等搭建的弄得环境来启动。需要把文件拷贝到搭建的环境目录里,费时费力无意中,我发现了一个好用的Node工具 很简单的名字: serve打包之后,发布后,可以直接启动ps,运行命令serve -s -p 8080如果在文件夹里边启动ps,直接serve就可以了如果实在文件夹外部,serve folder也可以了可以加端口号,-p 5001 默认是 5000","categories":[{"name":"工具","slug":"工具","permalink":"http://algate.github.io/categories/工具/"}],"tags":[{"name":"node","slug":"node","permalink":"http://algate.github.io/tags/node/"},{"name":"dependencies","slug":"dependencies","permalink":"http://algate.github.io/tags/dependencies/"}],"keywords":[{"name":"工具","slug":"工具","permalink":"http://algate.github.io/categories/工具/"}]},{"title":"uniapp大揭秘-初遇","slug":"uniapp大揭秘-初始","date":"2019-03-09T06:36:01.000Z","updated":"2019-12-24T08:11:20.506Z","comments":true,"path":"archives/201903091436.html","link":"","permalink":"http://algate.github.io/archives/201903091436.html","excerpt":"","text":"1.uniapp命令行命令行敲击的快感,谁用谁知道,so为的项目是vue安装项目的2.uniapp-pages.json要访问的每个页面都要在此文件中进行初始配置123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566{ pages:[{ \"path\": \"pages/ucenter/ucenter\", \"style\": { <!-- 此处为单个文件配置,不过不配置,优先使用globalStyle里的配置内容 --> \"navigationBarTitleText\": \"不谈理想\", \"navigationBarBackgroundColor\": \"#1C88E8\", \"navigationBarTextStyle\": \"white\", /* 是否开启下拉刷新 */ \"enablePullDownRefresh\" : true \"app-plus\": { \"bounce\": \"none\", <!-- titleNView设置为false,顶部导航就没有了 --> \"titleNView\": { \"buttons\": [{ \"text\": \"\\uf0e0\", \"fontSrc\": \"/static/fonts/fontawesome-webfont.ttf\", \"fontSize\": \"22px\", \"float\": \"left\" }, { \"text\": \"\\uf1de\", \"fontSrc\": \"/static/fonts/fontawesome-webfont.ttf\", \"fontSize\": \"22px\" }] } }, \"h5\": { }, /* 应用小程序组件 */ \"usingComponents\": { }, /* 窗口背景色 */ \"backgroundColor\": \"#ECEFF2\" } }], <!-- 页面菜单栏显示 --> \"tabBar\": { \"color\": \"#73787C\", \"selectedColor\": \"#1B88EF\", \"backgroundColor\": \"#FFFFFF\", \"borderStyle\": \"white\", \"list\": [{ \"pagePath\": \"pages/list/list\", \"iconPath\": \"static/home.png\", \"selectedIconPath\": \"static/home-active.png\", \"text\": \"发现\" },{ \"pagePath\": \"pages/bookrack/list\", \"iconPath\": \"static/home.png\", \"selectedIconPath\": \"static/home-active.png\", \"text\": \"书架\" },{ \"pagePath\": \"pages/idea/list\", \"iconPath\": \"static/home.png\", \"selectedIconPath\": \"static/home-active.png\", \"text\": \"想法\" }, { \"pagePath\": \"pages/ucenter/ucenter\", \"iconPath\": \"static/center.png\", \"selectedIconPath\": \"static/center-active.png\", \"text\": \"我\" }] }3.uniapp-manifest.json项目整体配置文件最近自己写项目遇到个问题,请求接口设置代理的问题,网上写的没有一个我能用的,最后在自己的不断尝试中竟然解决了。1.未设置DevServer,假如你8080端口号没被占用,启动项目,就是8080端口号2.假如8080端口号被占用,启动项目,就是8081.这个非常人性化了。假如先启动该项目,启动别的8080就不行了哦,注意3.router,base初始的时候是很长一段路径,我是为了解决代理问题才改的,你可以不改哦!4.proxy: pathRewrite-是吧路径中的字段替换成什么,跟你创建的vue,react等项目一样。1234567891011121314151617181920{ \"h5\" : { \"router\" : { \"base\" : \"/\" }, \"template\" : \"h5.template.html\", \"devServer\": { \"port\": 8081, \"disableHostCheck\": true, \"proxy\": { \"/api\": { \"target\": \"https://api.douban.com\", \"changeOrigin\": true, \"secure\": false, \"pathRewrite\": {\"^/api\" : \"\"} } } } }}这是我的配置文件,本想贴出原始代码的,不过,写这篇文章时,正好没有网络。","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"uniapp","slug":"uniapp","permalink":"http://algate.github.io/tags/uniapp/"},{"name":"移动端","slug":"移动端","permalink":"http://algate.github.io/tags/移动端/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]},{"title":"永久免费翻樯大杀器(不限速)","slug":"永久免费翻樯大杀器(不限速)","date":"2017-08-24T08:12:19.000Z","updated":"2019-12-25T06:43:50.653Z","comments":false,"path":"archives/61443.html","link":"","permalink":"http://algate.github.io/archives/61443.html","excerpt":"","text":"网上免费翻墙的网站、软件、账号越来越少了,不是要天天签到就是不定时更换帐号密码,速度不理想,也不稳定。今天推荐GFW.Press。需要翻墙注册,无翻墙软件的可下载Lantern,用法不多说,自己动手丰衣足食。现在已经大家都能够翻樯了.接下来就要使用免费服务了:1.登录gfw.press官网(这里需要翻樯)2.点击注册3.注册成功后点击登录,你将会看到节点信息4.下载gfw.press软件5.安装完毕后双击打开,并安装gfw.press官网中提供的账号填入节点,端口以及密码.6.打开谷歌浏览器,搜索chrome网上应用店,打开并搜索插件switchomega,安装插件 (这里需要翻樯)7.下载完毕后,你的谷歌浏览器右上角将多出一个小图标.单击选项按钮进入管理界面.8.进入管理界面后,进行如下配置新建情景模式填入路由信息","categories":[{"name":"工具","slug":"工具","permalink":"http://algate.github.io/categories/工具/"}],"tags":[{"name":"翻墙","slug":"翻墙","permalink":"http://algate.github.io/tags/翻墙/"}],"keywords":[{"name":"工具","slug":"工具","permalink":"http://algate.github.io/categories/工具/"}]},{"title":"JavaScript代码检查工具对比","slug":"JavaScript代码检查工具对比","date":"2017-04-03T07:51:30.000Z","updated":"2019-02-27T03:29:53.800Z","comments":true,"path":"archives/26064.html","link":"","permalink":"http://algate.github.io/archives/26064.html","excerpt":"","text":"JavaScript代码校验工具能够让你在写代码时避免一些低级的错误。尽管我有很多年的开发经验,我仍然会犯一些语法错误并且忘记处理我的错误。一个好的校验工具或者格式化工具,可以让我避免这些错误,以免浪费我的时间。一个好的校验工具还能确保一个项目保持一个固定的代码风格。有很多关于JavaScript的校验工具,你怎样选择其中的某一个呢?让我们一起来看看它们有什么样的特性以及优缺点。接下来我要介绍四种常用的选择:JSLint,JSHint,JSCS和ESLint。Overview这四个工具的基本用法都是类似的,它们定义了一套规则用来解析和报告js文件里面的问题。它们都可以通过npm来进行安装。可以通过命令行来调用它们,给命令行传递文件参数,也可以作为grunt这一类工具的插件被使用,或者可以集成到编辑器中。它们都支持使用注释作为配置。以上就是它们所有的相似之处了,每一个工具都有优缺点,只是有些工具相比于其它工具更加有优势。JSLintJSLint是这四种校验工具中最为古老的。Douglas Crockford(译注:《JavaScript 语言精粹》的作者)在2002年创造了它,它是强制使用的,为了保留它所认为的JavaScript这门语言的精华部分。如果你认同他的观点,对你而言,JSLint将会是一个好的工具。安装完成马上即可使用。JSLint的缺点是它是不可以进行配置和扩展的。你不能禁用它的某些特性,并且缺乏文档。它的官网并没有什么用处,例如,它缺少如果将这个工具整合到你的编辑器的任何信息。优点:配置规则都已经定好了,安装即可使用(如果你同意这些强制的规则的话)缺点:JSLint没有可配置文件,你无法对它的规则进行更改配置规则的数量有限,有些规则无法禁用不支持自定义规则缺少文档很难定位到哪条规则导致了错误JSCSCJSCS和以上两个都是不同的,如果不给它一个配置文件或者使用一套预设的规则,它将什么也不做不了,不过你可以从别的网站下载配置文件,所以这并不是什么大问题,并且它有很多的预设规则,比如说jQuery的代码风格的预设规则以及Google的代码风格的预设规则。它有超过90种不同的规则,并且你可以通过插件创造自定义规则。JSCS也支持自定义输出报告,这使得其更容易与需要其以特定格式输入的工具集成。JSCS是一个代码风格检查器,这意味着它只捕获与代码格式相关的问题,而不包含潜在的错误。因此,它比其他工具的灵活性更低,但是如果您需要强制执行特定的编码风格,那么JSCS就可以做的很好。优点:支持自定义输出报告,可以使其更容易和其它工具进行集成如果您遵循现有的可用编码风格之一,预设和现成的配置文件可以轻松设置在报告中,有一个标志包含在规则名之中,所以很容易找出是哪条规则导致了错误可以利用自定义的插件进行拓展缺点:只检测到代码风格的违规,不检测潜在的错误,比如说未使用的变量或者变量的全局污染等四个工具中性能最差的,但是这并不是一个典型用途的问题ESLintESLint是这四个工具中最新的,它被设计为易于拓展的,具有大量的自定义规则,并且很容易通过插件的形式来安装。它输出简洁的报告,但是默认包含规则的名称,因此你始终知道是那条规则导致了错误的信息。ESLint的文档多少有些混乱,规则的列表容易查找,并且按逻辑进行分类,但配置说明在某些地方有点混乱。然而,它提供了如何对编辑器进行集成,插件和示例的链接。优点:灵活:任何规则都可以切换使用,并且有些规则有额外的配置可以使用可拓展性好,并且有很多可用的插件易于理解的输出报告包含一些其它工具所没有的规则,使得ESLint更容易检测出代码中潜在的错误对ES6的支持性最好,是唯一支持JSX的工具支持自定义输出报告缺点:需要一些配置性能差,但这并不是主要的障碍推荐一个好的校验工具是捕捉问题非常重要的一步,但是它只能检测出它的规则许可范围之内的错误。对于更多简单明了的bug的捕捉,我建议使用单元测试,Code reviews也是也是不错的方式。","categories":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}],"tags":[{"name":"JavaScript","slug":"JavaScript","permalink":"http://algate.github.io/tags/JavaScript/"},{"name":"jsLint","slug":"jsLint","permalink":"http://algate.github.io/tags/jsLint/"}],"keywords":[{"name":"前端","slug":"前端","permalink":"http://algate.github.io/categories/前端/"}]}]}