关于node.js:NodeJS中与爬虫相关的常见加密

NodeJS中的Crypto应用在爬虫JS解密的时候常常会遇到常见的加密,例如:MD5,Sha1,Sha256,AES,RSA等加密算法,这些能够在Python中调用,当然有时候采纳NodeJS调用也很不便,相熟NodeJS常见的加密算法对逆向JS很有帮忙。NodeJS 中的 Crypto 模块提供了加密性能,包含对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证性能的一整套封装。 Hash将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规定就是哈希算法,而通过原始数据映射之后失去的二进制值串就是哈希值(散列值).一个优良的哈希算法须要满足: 从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法);对输出数据十分敏感,哪怕原始数据只批改了一个 Bit,最初失去的哈希值也大不相同;散列抵触的概率要很小,对于不同的原始数据,哈希值雷同的概率十分小;哈希算法的执行效率要尽量高效,针对较长的文本,也能疾速地计算出哈希值。哈希算法严格来说并不属于加密算法,传统意义上的 加密 是与 解密 相配对的。哈希算法只能加密不能反向解密。 MD5在NodeJS中 MD5 Hash 函数的用法如下: const crypto = require('crypto');const hash = crypto.createHash('md5');console.log(hash.update('666666').digest('hex'))// f379eaf3c831b04de153469d1bec345econst hash2 = crypto.Hash('md5');console.log(hash2.update('666666').digest('hex'))// f379eaf3c831b04de153469d1bec345e其中摘要的编码方式有如下三种: latin1hexbase64Sha1const crypto = require('crypto');const hash = crypto.createHash('sha1');console.log(hash.update('666666').digest('hex'))// 1411678a0b9e25ee2f7c8b2f7ac92b6a74b3f9c5const hash2 = crypto.Hash('sha1');console.log(hash2.update('666666').digest('hex'))// 1411678a0b9e25ee2f7c8b2f7ac92b6a74b3f9c5Base64百度百科中对Base64有一个很好的解释:“Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来示意二进制数据的办法”。什么是“可打印字符”呢?为什么要用它来传输8Bit字节码呢?在答复这两个问题之前咱们有必要来思考一下什么状况下须要应用到Base64?Base64个别用于在HTTP协定下传输二进制数据,因为HTTP协定是文本协定,所以在HTTP协定下传输二进制数据须要将二进制数据转换为字符数据。然而间接转换是不行的。因为网络传输只能传输可打印字符。什么是可打印字符?在ASCII码中规定,0~31、127这33个字符属于控制字符,32~126这95个字符属于可打印字符,也就是说网络传输只能传输这95个字符,不在这个范畴内的字符无奈传输。那么该怎么能力传输其余字符呢?其中一种形式就是应用Base64。 Base64,就是应用64个可打印字符来示意二进制数据的办法。Base64的索引与对应字符的关系如下表所示: 更加具体的解释能够参考:什么是Base64? 严格来说Base64也不是加密算法,然而爬虫中也会常常遇到,所以在此给出在NodeJS中的Base64的"加密"与"解密"。在浏览器中加密与解密别离对应 btoa 和 atob。 Base64加密对应浏览器中的 btoa: const data = '666666';const encodedData = Buffer.from(data, 'utf-8').toString('base64'); // 输出编码为utf8,输入为base64console.log(encodedData);// NjY2NjY2Base64解密对应浏览器中的 atob: const data = 'NjY2NjY2';const decodedData = Buffer.from(data, 'base64').toString('utf8'); // 输出编码为base64,输入编码为utf8console.log(decodedData);// 666666DESDES 是 Data Encryption Standard(数据加密规范)的缩写。它是由IBM公司研制的一种对称明码算法,美国国家标准局于1977年颁布把它作为非机要部门应用的数据加密规范,它始终沉闷在国内窃密通信的舞台上,表演了非常重要的角色。 ...

November 16, 2020 · 1 min · jiezi

关于node.js:Nodejs-中文文档

 Node.js 中文文档assert - 断言async_hooks - 异步钩子Buffer - 缓冲器child_process - 子过程cluster - 集群console - 控制台crypto - 加密debugger - 调试器dgram - 数据报dns - 域名服务器domain - 域Error - 谬误events - 事件触发器fs - 文件系统global - 全局变量http - HTTPhttp2 - HTTP/2https - HTTPSinspector - 查看器module - 模块net - 网络os - 操作系统path - 门路perf_hooks - 性能钩子process - 过程punycode - 域名代码querystring - 查问字符串readline - 逐行读取repl - 交互式解释器stream - 流string_decoder - 字符串解码器timer - 定时器tls - 平安传输层trace_events - 跟踪事件tty - 终端url - URLutil - 实用工具v8 - V8引擎vm - 虚拟机wasi - WASIworker_threads - 工作线程zlib - 压缩*对于本文档用法与示例C++ 插件C++ 嵌入器N-API命令行选项CommonJS 模块ECMAScript 模块包模块安全策略诊断报告国际化反对弃用的 API

November 15, 2020 · 1 min · jiezi

关于node.js:imook-nodejs个人学习笔记日志

总结:应用fs的api读写文件,把日志存在文本中,设置crontab定时拆分日志。7.1 日志拜访日志access log 零碎中 (零碎中最重要的日志)自定义日志 自定义事件 自定义谬误等nodejs的文件操作 nodejs stream 日志的开发和应用日志的拆分、日志内容分析写文件是一个异步的,不须要立刻去写。用redis太节约。mysql 是表构造,不适宜,也不必部署,也节约。文件的老本比拟低。 7.2 nodejs 文件操作const fs = require('fs');const path = require('path');const fileName = path.resolve(__dirname, 'data.log');// 读取文件内容fs.readFile(fileName, (err, data) => { if (err) { console.log(err); return } // data 是二进制,须要转换成字符串 console.log(data.toString());})// 写入文件const content = "市民胡女士还是小仙女";const opt = { flag: 'a'}fs.writeFile(fileName, content, opt, (err) => { if (err) { console.log(err); return; }})// 判断文件是不是存在fs.exists(fileName, (exists) => { console.log("exists:", exists);})7.3 stream 介绍性能瓶颈:IO、网络IO、文件IO 。相比于CPU计算和内存读写,IO的次要特点就是慢。如何在无限的硬件资源下,进步IO的操作效率。 ...

November 10, 2020 · 1 min · jiezi

关于node.js:nodejs篇手写koa中间件

koa-statickoa-static能够解决动态资源,参数是动态资源文件夹门路,官网的实现蕴含了更多的参数配,具体能够查看 koajs/static实现剖析: 获取申请url门路,查找动态文件夹下的门路是否能匹配如果是门路是文件夹,查找文件夹下index.html文件设置响应头文件类型(mime)gzip压缩,设置压缩类型并返回可读流出错或文件不存在next持续下一个中间件const fs = require("fs")const path = require("path")const mime = require("mime")const zlib = require("zlib")function static(dir) { return async (ctx, next) => { try { let reqUrl = ctx.path let abspath = path.join(dir, reqUrl) let statObj = fs.statSync(abspath) // 如果是文件夹,拼接上index.html if (statObj.isDirectory()) { abspath = path.join(abspath, "index.html") } // 判断门路是否精确 fs.accessSync(abspath); // 设置文件类型 ctx.set("Content-Type", mime.getType(abspath) + ";charset=utf8") // 客户端容许的编码格局,判断是否须要gzip压缩 const encoding = ctx.get("accept-encoding") if (/\bgzip\b/.test(encoding)) { ctx.set("Content-Encoding", "gzip") ctx.body = fs.createReadStream(abspath).pipe(zlib.createGzip()) } else if (/\bdeflate\b/.test(encoding)) { ctx.set("Content-Encoding", "bdeflate") ctx.body = fs.createReadStream(abspath).pipe(zlib.createDeflate()) } else { ctx.body = fs.createReadStream(abspath) } } catch (error) { await next() } }}module.exports = statickoa-bodyparserkoa-bodyparser能够解决POST申请的数据,将form-data数据解析到ctx.request.body,官网地址:koa-bodyparser ...

November 9, 2020 · 3 min · jiezi

关于node.js:使用流读文件写文件处理大文件

解决大文件读写 流streamfs.createReadStreamcreateReadStream 是fs模块外面读流的一个办法 createReadStream 读取文件,有两个参数第一个参数,读取文件的门路第二个参数 highWaterMark 最高水位线,默认最多读取64K读取的类容都是buffer类型返回的后果是一个可读流的实例,是非流动模式---咱们最初要转为流动模式先要定义一下咱们读流的变量,假如咱们有一个1.txt文件,咱们要读取1.txt外面的类容咱们先设置最高水位线每次读取1klet rs=fs.createReadStream('./1.txt',{highWaterMark:1}) 咱们的rs外面有绑定了两个事件办法data和end fs.createWriteStreamconst fs = require('fs');const path = require('path');let readPath = path.join(__dirname, `./dist/my.txt`);let copyPath = path.join(__dirname, './dist/my.txt');// 实现每次读取文件实时写入 将新的buffer存入数组 而后转成buffersave(`--:第2次退出:--`);async function save(value) { // 读取文件 const localBufArr = await readFileStream(readPath); let totalLength = 0;// 增加新进入的buffer localBufArr.push( new Buffer(value,['utf8'])); localBufArr.map(v => { totalLength += v.length })// buffer 合并 let buf = Buffer.concat(localBufArr, totalLength); // buffer合并 将数组buffer转成整个buffer console.log('buf',buf);// 创立可写流 let firstCreate = fs.createWriteStream(copyPath);// 写入buffer firstCreate.write(buf);}// 读文件 用流function readFileStream(spath) { return new Promise((resolve, reject) => { // 判断文件是否存在 if (fs.existsSync(spath)) { let readStream = fs.createReadStream(spath); let arr = []; let startTime = Date.now(); // 在外部一直触发rs.emit('data',数据);data不能更改,留动模式开启后,数据会疯狂触发data事件 readStream.on('data', function (chunk) { //chunk是buffer类型 arr.push(chunk) }) // 监听文件读取结束,会主动触发一次end事件,没有读取完是不会触发的 readStream.on('end', function (chunk) { let useTime = Date.now() - startTime; console.log("读文件用" + (useTime/1000) +"s") resolve(arr) }) // 监听谬误 readStream.on('error', function (err) { console.log(err); }) } else { reject("没有改文件") } }) }

November 9, 2020 · 1 min · jiezi

关于node.js:nodejs篇实现一个koa

实现koa有这几个次要步骤: 封装httpServer上下文context和request、response对象中间件函数 middleware错误处理koa 外围源码外面包含这几个文件: |-- koa |-- lib |-- application.js |-- context.js |-- request.js |-- response.js入口文件 applicationapplication.js是外围入口文件,包含导出Koa类函数和外围代码的实现: const http = require("http")class Koa { constructor() { // 上下文 context this.ctx = Object.create({}); // 中间件函数 this.middleware = null } use(fn) { // 将用户传入的函数绑定到中间件函数中 this.middleware = fn } handleRequest(req, res) { let ctx = this.ctx; // 给上下文增加 request 和 response 对象 ctx.req = req; ctx.res = res; // 执行中间件函数 this.middleware(ctx); // 返回后果 ctx.body ? res.end(ctx.body) : res.end("Not Found") } listen() { let server = http.createServer(this.handleRequest.bind(this)) server.listen(...arguments) }}module.exports = Koa;下面的代码曾经实现了httpServer服务的封装,有最根底的context上下文对象,绑定了request和response属性,能够在根目录下创立index.js文件测试: ...

November 6, 2020 · 3 min · jiezi

关于node.js:NodeJs通过Unirest方式对接不上短信验证码接口的尴尬经历

你遇到过NodeJs通过Unirest形式无奈调用短信验证码接口的经验吗?通过大半天的调试,终于完满的解决了,示例中的接口是用各大云市场短信供应商的短信接口,上面就是我解决的方法,代码如下: `var unirest = require('unirest');var req = unirest('POST', 'https://vip.veesing.com/smsAp...') .headers({ 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}) .send('appId=41KYR0EB**') .send('appKey=IIWCKKSR7NOQ**') .send('phone=1561894**') .send('templateId=1043') .send('variables=1234') .end(function (res) { if (res.error) throw new Error(res.error); console.log(res.raw_body);});` 短信的概念早在1984年就呈现了,1992年12月3日公布了首条短信,而短信验证码则是避免有人利用机器人主动批量注册、对特定的注册用户用特定程序暴力破解形式进行一直的登陆、灌水。 NodeJs - Unirest.js和文档阐明下载

November 6, 2020 · 1 min · jiezi

关于node.js:用了这么久的Scheduled你知道它的实现原理吗

这两天应用Scheduled注解来解决定时问题的时候,发现不能失常应用。所以就有了这一篇博客 @Scheduled(initialDelay = 2000,fixedDelay = 1000)private void test(){ System.out.println(Math.random());}单从源码的doc文件中能够看到这么一段 You can add the `@Scheduled` annotation to a method, along with trigger metadata. Forexample, the following method is invoked every five seconds with a fixed delay,meaning that the period is measured from the completion time of each precedinginvocation:[source,java,indent=0][subs="verbatim,quotes"]---- @Scheduled(fixedDelay=5000) public void doSomething() { // something that should run periodically }----将源码放进我的环境运行,发现并不能失效。那就只能先看看源码来看看它到底是怎么失效的 注解Scheduled的源码 @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Repeatable(Schedules.class)public @interface Scheduled { String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED; String cron() default ""; String zone() default ""; long fixedDelay() default -1; String fixedDelayString() default ""; long fixedRate() default -1; String fixedRateString() default ""; long initialDelay() default -1; String initialDelayString() default "";}而后,动静加载的代码在 ScheduledAnnotationBeanPostProcessor 的 postProcessAfterInitialization 办法中 ...

November 5, 2020 · 5 min · jiezi

关于node.js:记不住Spring中Scheduled中的Cron语法让我们看看源码吧

在Spring源码中,解析cron的源码位于CronExpression中,在创立定时工作的时候,调用了CornExpression.parse办法做解析 public CronTrigger(String expression, ZoneId zoneId) { Assert.hasLength(expression, "Expression must not be empty"); Assert.notNull(zoneId, "ZoneId must not be null"); this.expression = CronExpression.parse(expression); this.zoneId = zoneId;}那当初就让咱们揭开解析cron表达式的神秘面纱 public static CronExpression parse(String expression) { Assert.hasLength(expression, "Expression string must not be empty"); // 如果 expression 是注解模式,就将注解替换为上面的模式(见尾部) expression = resolveMacros(expression); // StringUtils.tokenizeToStringArray 与 split办法性能差不多 String[] fields = StringUtils.tokenizeToStringArray(expression, " "); if (fields.length != 6) { // cron表达式必须由六项组成 throw new IllegalArgumentException(String.format( "Cron expression must consist of 6 fields (found %d in \"%s\")", fields.length, expression)); } try { CronField seconds = CronField.parseSeconds(fields[0]); // 第一项是秒 CronField minutes = CronField.parseMinutes(fields[1]); // 第二项是分 CronField hours = CronField.parseHours(fields[2]); // 第三项是时 CronField daysOfMonth = CronField.parseDaysOfMonth(fields[3]); // 第四项是日 CronField months = CronField.parseMonth(fields[4]); // 第五项是月 CronField daysOfWeek = CronField.parseDaysOfWeek(fields[5]); // 第六项是年 return new CronExpression(seconds, minutes, hours, daysOfMonth, months, daysOfWeek, expression); } catch (IllegalArgumentException ex) { String msg = ex.getMessage() + " in cron expression \"" + expression + "\""; throw new IllegalArgumentException(msg, ex); }}// resolveMacros 函数private static String resolveMacros(String expression) { expression = expression.trim(); for (int i = 0; i < MACROS.length; i = i + 2) { if (MACROS[i].equalsIgnoreCase(expression)) { return MACROS[i + 1]; } } return expression;}private static final String[] MACROS = new String[] { "@yearly", "0 0 0 1 1 *", "@annually", "0 0 0 1 1 *", "@monthly", "0 0 0 1 * *", "@weekly", "0 0 0 * * 0", "@daily", "0 0 0 * * *", "@midnight", "0 0 0 * * *", "@hourly", "0 0 * * * *"};当初,cron表达式的程序咱们就记住,必须是六项,程序是 秒,分,时,日,月,年或者用零碎中定义的MACROS来代替,六项两头用空格隔开。那么到底每一项是怎么解析和表白的呢?来看看CronField中的相干定义。 ...

November 5, 2020 · 5 min · jiezi

关于node.js:从Spring源码中学习如何查找自定义注解

看几个根底的注解 @AliasFor@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Documentedpublic @interface AliasFor { @AliasFor("attribute") String value() default ""; @AliasFor("value") String attribute() default ""; Class<? extends Annotation> annotation() default Annotation.class;}AliasFor这个注解很奇怪,value的别名是attribute,attribute的别名是value 那么它的行为在哪里被定义的呢?在AnnotationTypeMapping中咱们能够找到答案 // 这里应用了AnnotationsScanner的getDeclaredAnnotation办法来获取所有的AliasFor注解的办法// AnnotationsScanner 是spring中的非公开抽象类,在咱们的代码中不能间接进行应用// Spring中没有提供子类private Map<Method, List<Method>> resolveAliasedForTargets() { Map<Method, List<Method>> aliasedBy = new HashMap<>(); for (int i = 0; i < this.attributes.size(); i++) { Method attribute = this.attributes.get(i); AliasFor aliasFor = AnnotationsScanner.getDeclaredAnnotation(attribute, AliasFor.class); if (aliasFor != null) { Method target = resolveAliasTarget(attribute, aliasFor); aliasedBy.computeIfAbsent(target, key -> new ArrayList<>()).add(attribute); } } return Collections.unmodifiableMap(aliasedBy);}// 为了简洁,我将源代码中其余部分省略掉了,能够看到,这里应用用反射失去的Method的getAnnotation办法失去实例private Method resolveAliasTarget(Method attribute, AliasFor aliasFor, boolean checkAliasPair) { // ... ... Method target = AttributeMethods.forAnnotationType(targetAnnotation).get(targetAttributeName); // ... ... if (isAliasPair(target) && checkAliasPair) { AliasFor targetAliasFor = target.getAnnotation(AliasFor.class); if (targetAliasFor != null) { Method mirror = resolveAliasTarget(target, targetAliasFor, false); if (!mirror.equals(attribute)) { throw new AnnotationConfigurationException(String.format( "%s must be declared as an @AliasFor %s, not %s.", StringUtils.capitalize(AttributeMethods.describe(target)), AttributeMethods.describe(attribute), AttributeMethods.describe(mirror))); } } } return target;}通过学习@AliasFor,咱们晓得了能够通过先流动Method,再或得其润饰的注解的办法。 ...

November 4, 2020 · 2 min · jiezi

关于node.js:原来用NodeJs-Axios实现短信验证功能这么简单

短信验证性能可用户我的项目的注册登录以及预警揭示等场景,NodeJs通过 Axios形式实现短信验证的形式非常简单,上面是用各大云市场短信供应商的短信接口作为演示示例,代码如下: `var axios = require('axios');var qs = require('qs');var data = qs.stringify({ 'appId': '41KYR0EB**','appKey': 'IIWCKKSR7NOQ**','phone': '1561894**','templateId': '1043','variables': '1234' });var config = { method: 'post', url: 'https://vip.veesing.com/smsAp...', headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}, data : data}; axios(config).then(function (response) { console.log(JSON.stringify(response.data));}).catch(function (error) { console.log(error);});` 留神了,上面才是重点: 1、短信验证码肯定要配合图形验证应用 2、短信接口的稳定性和费用也很重要 3、留神限度单个号码每日可获取验证码的最大数量 NodeJs - Axios.js和文档阐明下载

November 4, 2020 · 1 min · jiezi

关于node.js:NG全家桶全栈项目实践总结

前言Angular在国内应用的人并不像国外那么多,根本都是外企在用,但其框架的思维却仍能够为咱们所借鉴,在某些问题没有思路的时候能够参考ng相干的解决,ng解决形式和思维的确比拟超前,但也因而而曲高和寡。本文旨在通过ng全家桶我的项目(前端Angular10 + 后端NestJS7)的实际来总结对于ng架构中一些亮点的关注与思考,Angular和Nest在前后端框架的解决上同出一脉,比照起来更有借鉴意义。 目录前端我的项目实际后端我的项目实际源码简析案例前端我的项目实际 [目录构造] src app login login.component.htmllogin.component.scsslogin.component.spec.tslogin.component.tsmain main.component.htmlmain.component.scssmain.component.spec.tsmain.component.tsapp.component.htmlapp.component.scssapp.component.spec.tsapp.component.tsapp.module.tsapp.service.tsuser.tsmain.tsindex.htmlangular.json[目录形容] 整个前端我的项目是基于angular脚手架生成的,其根本目录构造是在src的app下进行相干组件和页面的模块开发,main.ts和index.html是整个单页利用的主入口,根目录下angular.json用于配置相干的打包编译等环境配置参数 [实际分享] 脚手架版本问题:对于ng10.1.x以上的版本其脚手架版本与库版本有出入,会导致引入HttpModule及其他局部模块时报错,须要将@angular/compiler这个库进行相干版本的降级 This likely means that the library (@angular/common/http) which declares HttpClientModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.输入框双向数据绑定有效问题:对于forms表单的想应用[(ngModal)]指令,必须在module中引入FormsModuleimport { FormsModule } from '@angular/forms';@NgModule({ imports: [ FormsModule ]})组件库应用有问题:目前ng的组件库次要有 官网 MATERIAL 组件库、NG-ZORRO 组件库、NG-NEST 组件库,但这几个次要的组件库都在10以下或10.0版本,会有局部bug,因此本次未引入组件库,间接应用html和scss来优化页面Animation引入问题:同样的跟版本有关系,想应用ng自带的animation动画库须要配合对应的版本,在做提示框隐没时本想应用ng的动画,起初改用了animation间接写.app-message { width: 300px; height: 40px; background: #fff; transition: all 2s none; border: 1px solid #ececec; border-radius: 4px; position: fixed; left: 50%; top: 10px; margin-left: -150px; text-align: center; &-show { animation: a 3s ease-out forwards; animation-direction: alternate; animation-iteration-count: 1; @keyframes a { 0% {opacity: 1;} 100% {opacity: 0;} } } &-hide { opacity: 0; }}后端我的项目踩坑实际 ...

November 4, 2020 · 6 min · jiezi

关于node.js:从源码角度学习java函数式编程

Java 函数式编程简略来说,函数式编程就是被注解@FunctionalInterface润饰的接口。 @Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface FunctionalInterface {}// 以jdk中的LongToIntFunction,相当于就是一个接口@FunctionalInterfacepublic interface LongToIntFunction { /** * Applies this function to the given argument. * * @param value the function argument * @return the function result */ int applyAsInt(long value);}// 这个接口能够被间接传入到函数中间接应用// 以jdk中的LongPipeline为例@Overridepublic final IntStream mapToInt(LongToIntFunction mapper) { Objects.requireNonNull(mapper); return new IntPipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Long> opWrapSink(int flags, Sink<Integer> sink) { return new Sink.ChainedLong<Integer>(sink) { @Override public void accept(long t) { downstream.accept(mapper.applyAsInt(t)); } }; } };}那么,函数是编程的interface怎么实现呢?由之前讲注解的时候咱们提到了,jdk内置的元注解,编译器是会辨认并给被该注解润饰的对象赋予编译器事后定义好的行为的。 ...

November 3, 2020 · 2 min · jiezi

关于node.js:electronegg

electron-egg一个疾速、功能丰富的桌面软件开发框架,基于electron和egg.js 个性能够用服务端的开发思维,来编写桌面软件也能够用前端来开发,数据服务申请内部api即可服务端的技术场景简直都能够应用,如:路由、中间件、控制器、服务、定时工作、队列、插件等桌面软件常见性能,后续逐渐集成并欠缺或提供demo。开始应用下载 # giteegit clone https://gitee.com/wallace5303/electron-egg.git# githubgit clone https://github.com/wallace5303/electron-egg.git启动 # 进入目录 ./electron-egg/npm installnpm run dev常用命令 # 开发者模式npm run dev# 生产者模式npm run start# 打包 (windows版本)npm run build-w# 打包 (mac版本)npm run build-m# 打包 (linux版本)npm run build-l日志electron日志:./logs/main.logegg日志:./logs/我的项目案例网址治理巨匠体验 注:# 分割作者(邮箱:530353222@qq.com)展现你的我的项目 进行中性能软件自动更新数据本地存储mac版性能兼容欢送star

November 3, 2020 · 1 min · jiezi

关于node.js:搭建node服务四Decorator装饰器

Decorator(装璜器)是ECMAScript中一种与class相干的语法,用于给对象在运行期间动静的减少性能。Node.js还不反对Decorator,能够应用Babel进行转换,也能够在TypeScript中应用Decorator。本示例则是基于TypeScript来介绍如何在node服务中应用Decorator。 一、 TypeScript相干因为应用了 TypeScript ,须要装置TypeScript相干的依赖,并在根目录增加 tsconfig.json 配置文件,这里不再具体阐明。要想在 TypeScript 中应用Decorator 装璜器,必须将 tsconfig.json 中 experimentalDecorators设置为true,如下所示: tsconfig.json{ "compilerOptions": { … // 是否启用实验性的ES装璜器 "experimentalDecorators": true }}二、 装璜器介绍1. 简略示例Decorator理论是一种语法糖,上面是一个简略的用TypeScript编写的装璜器示例: const Controller: ClassDecorator = (target: any) => { target.isController = true;};@Controllerclass MyClass {}console.log(MyClass.isController); // 输入后果:trueController是一个类装璜器,在MyClass类申明前以 @Controller 的模式应用装璜器,增加装璜器后MyClass. isController 的值为true。编译后的代码如下: var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r;};const Controller = (target) => { target.isController = true;};let MyClass = class MyClass {};MyClass = __decorate([ Controller], MyClass);2. 工厂办法在应用装璜器的时候有时候须要给装璜器传递一些参数,这时能够应用装璜器工厂办法,示例如下: ...

November 3, 2020 · 8 min · jiezi

关于node.js:Springboot以方便闻名那么你知道其简便性的核心java注解的原理嘛

java注解用法一个简略的注解 @Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Test1 { String name() default "123"; String[] name2() default {"123","342432","321321321"};}// public class Test2{ @Test1(name = "2313122313",name2 = {"312231321","4342","65456543"}) public static void sayHello(){ System.out.println("123"); } public static void main(String[] args){ sayHello(); }}有几个中央须要留神一下,首先@interface是编译器辨认的,表明该类型是一个继承了java.lang.annotation.Annotation接口的子接口,称之为注解。@Target和@Retention都是jdk中定义好的注解,前者次要表明该注解能够用于润饰什么,而后者次要确定该注解保留的环境,即能够在哪些环境中运行,是编译期,运行期还是编写代码的时候。 public enum ElementType { TYPE, // Class, interface (including annotation type), or enum declaration FIELD, // Field declaration (includes enum constants) METHOD, // Method declaration PARAMETER, // Formal parameter declaration CONSTRUCTOR, // Constructor declaration LOCAL_VARIABLE, // Local variable declaration ANNOTATION_TYPE, //Annotation type declaration PACKAGE, // Package declaration TYPE_PARAMETER, // type parameter declaration TYPE_USE // Use of a type}public enum RetentionPolicy { SOURCE, CLASS, RUNTIME}下面两个枚举类型别离是注解保留机会(编码期,编译期,运行期)和作用范畴,也是注解最为外围的属性。 ...

November 2, 2020 · 2 min · jiezi

关于node.js:npm基本命令

npm根本命令 npm install xxx 装置xxx模块,但不记录到package.json里 npm install xxx@版本号 装置指定版本号的xxx模块 npm install --save xxx 装置xxx模块,并且记录到package.json里,字段对应的dependency,是产品环境必须依赖的模块 npm install --save-dev xxx 装置xxx模块,并且记录到package.json里,字段对应的dev-dependency,是开发环境必须依赖的模块 npm install --global xxx 全局装置xxx模块,不记录到package.json npm uninstall xxx删除xxx模块 npm uninstall -g xxx全局删除xxx模块

November 2, 2020 · 1 min · jiezi

关于node.js:原创90的人都不会做的一道笔试题

关注“Java后端技术全栈”** 回复“面试”获取全套大厂面试材料 数组操作的题目,有的的确比拟容易,但并非每个问题都是如此。明天就来看道90%的人都不会做的口试题。请看题: 给你一个数组 nums 和一个值 val,你须要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要应用额定的数组空间,你必须仅应用 O(1) 额定空间并 原地 批改输出数组。 元素的程序能够扭转。你不须要思考数组中超出新长度前面的元素。 示例: 给定 nums = [3,1,4,3], val = 3,函数应该返回新的长度 2,并且 nums 中的前两个元素均为 2。你不须要思考数组中超出新长度前面的元素。 请临时不要看上面,先思考一下,有没有解答思路。 先 思 考 再 看 ! ! ! 解题思路: 当初思考数组蕴含很少的要删除的元素的状况。例如,num=[1,2,3,5,4],Val=4。依照很多人的思维会对前四个元素进行复制操作,其实咱们没必要对前四个元素做复制操作。另一个例子是 num=[4,1,2,3,5],Val=4。也仿佛没有必要将 1,2,3,5 这几个元素左移一步,因为问题形容中提到元素的程序能够更改。 实现 当咱们遇到 nums[i] = val 时,咱们能够将以后元素与最初一个元素进行替换,并开释最初一个元素。这实际上使数组的大小缩小了 1。 请留神,被替换的最初一个元素可能是您想要移除的值。然而不要放心,在下一次迭代中,咱们依然会查看这个元素。 最多遍历 n 步。在这个办法中,赋值操作的次数等于要删除的元素的数量。因而,如果要移除的元素很少,效率会更高。 代码如下: public static int removeElement(int[] nums, int val) {        if(nums == null){            return 0;        }        int i = 0;        int n = nums.length;        while (i < n) {            //如果相等            //(留神当以后元素是5的时候,此时i并没有加1)            if (nums[i] == val) {                //以后这个地位                nums[i] = nums[n - 1];                //数组大小减1                n--;            } else {                i++;            }        }        return n;    }测试 场景1:数组为null; public static void main(String[] args) {        int[] nums =null;         int val = 5;        System.out.println(removeElement(nums, val));    }后果 场景2:数组中只有一个5 public static void main(String[] args) {         int[] nums ={5};         int val = 5;        System.out.println(removeElement(nums, val));    }后果 ...

November 2, 2020 · 1 min · jiezi

关于node.js:HTTP消息头常见应用

Accept-LanguageAccept-Language通常用来实现多语言: Accept-Language: <language>Accept-Language: *// Multiple types, weighted with the quality value syntax:Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5;q= (q-factor weighting) 示意优先程序,用绝对品质价值示意,又称为权重。 简略实现: const http = require("http")const languages = {zh: "你好",en: "hello",jp: "こんにちは",}const server = http.createServer((req, res) => { res.setHeader("Content-Type", "text/plain;charset=utf-8") let lang = req.headers["accept-language"] // zh-CN,zh;q=0.9,en;q=0.8 if (!lang) return res.end("") lang = lang .split(",") .filter((t) => t.includes(";")) .map((t) => { let [name, q] = t.split(";") return { name, q: q.slice(2) * 1, } }) .sort((a, b) => a.q > b.q) for (let i = 0; i < lang.length; i++) { let work = languages[lang[i].name] if (work) { res.end(work) break } } res.end(JSON.stringify(lang))})server.listen(3000, () =>console.log(`Serving on: \r\n http://localhost:3000`))Accept-RangesHTTP申请范畴 ...

November 1, 2020 · 3 min · jiezi

关于node.js:JavaScript实现网页截屏方法总结

最近钻研了下如何利用JavaScript实现网页截屏,包含在浏览器运行的JS,以及在后盾运行的nodeJs的办法。次要看了以下几个: PhantomJSPuppeteer(chrome headless)SlimerJSdom-to-imagehtml2canvas测试的网页应用了WebGL技术,所以上面的总结会和WebGL相干。 名词定义headless browser无界面浏览器,多用于网页自动化测试、网页截屏、网页的网络监控等。 PhantomJSPhantomJS是能够通过JS进行编程的headless浏览器,应用的是QtWebKit内核。 实现截屏的代码,假如文件名为github.js: // 创立一个网页实例var page = require('webpage').create();// 加载页面page.open('http://github.com/', function () { // 给网页截屏,保留到github.png文件中 page.render('github.png'); phantom.exit();})运行: phantomjs github.js一般的页面没有问题,然而如果运行蕴含WebGL的页面,发现截屏不对。通过一些考察,发现不反对WebGL,github issue。 总结: PhantomJs曾经进行保护了,所以不太倡议持续应用。进行保护的一个起因是chrome公布的headless版本对它造成了肯定冲击。不反对WebGL。然而,还是有开发者说能够本人给PhantomJS增加WebGL反对,不过,这个计划目前超出我的常识范畴了,就没有持续钻研。Puppeteer(chrome headless)Puppeteer是一个Node库,提供了管制chrome和chromium的API。默认运行headless模式,也反对界面运行。 实现截屏的代码example.js: const puppeteer = require('puppeteer');(async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setViewport({ // 设置视窗大小 width: 600, height: 800 }); await page.goto('https://example.com'); // 关上页面 await page.screenshot({path: 'example.png'}); // path: 截屏文件保留门路 await browser.close();})();运行: node example.js接下来看下screenshot办法的实现原理: ...

October 31, 2020 · 2 min · jiezi

关于node.js:NodejsExpress后端实现上传文件并保存到数据库

NodeJS全栈开发之后端实现上传文件性能并保留到Mysql数据库 装置第三方插件multernpm i --save multer 创立上传接口文件upload.jsvar createFolder = function(folder){ try{ fs.accessSync(folder); }catch(e){ fs.mkdirSync(folder);} };var uploadFolder = './uploads/'; //文件上传地位 createFolder(uploadFolder);var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, uploadFolder)},filename: function (req, file, cb) { cb(null, file.originalname)}}) var upload = multer({ storage: storage }) //上传接口router.post('/upload', upload.single('file'), function(req, res) { fs.rename(req.file.path, "uploads/" + req.file.originalname, function(err) { if (err) { throw err; } var data= req.file var photo=req.file.url res.send({ code:CODE_SUCCESS, msg:'上传胜利', data:data }) //增加到数据库 const query = `insert into sys_data(photo) values( '${photo}')`; querySql(query) .then(data => { res.json({ code: CODE_SUCCESS, msg: '增加数据胜利', data: null }) }) })}) ...

October 31, 2020 · 1 min · jiezi

关于node.js:全国行政区域数据保存成json文件

简介全国行政区域json文件, 包含省,市,区,县,镇,街道 保留目录data│ ├─1 │ ├─2│ ├─3│ └─41 省2 市3 区/县4 镇/街道依据层级构造保留在不同的文件夹中,文件的命名都是下级区域的id。 比方北京的id是110000,那么海淀区所在的文件名称就是110000.json 以此类推 # 启动我的项目 下载代码到本机 $ git clone https://github.com/lizeze/china_region.git装置依赖 $ cd china_region $ npm i $ npm start关上浏览器拜访http://localhost:96/ 做了一个简略的demo,https://xx996.cn/xzqy 须要数据点这里 https://github.com/lizeze/chi...

October 30, 2020 · 1 min · jiezi

关于node.js:Nodejs代码安全方案

背景私有化部署的我的项目防止源码被浏览、剖析。这个我的项目安全等级没有特地高,因为一系列起因还是用了Node.js。没有相对的平安,只能减少破解的老本。 计划 实现合并为单文件应用webpack构建工具来实现,指定入口文件,将所有依赖模块打成一个bundle。Nodejs内置模块无奈打进bundle,也没方法辨别内置模块及第三方依赖,所以这两局部间接排除掉,只将工程中源码进行合并。 module.exports = { entry: [ './src/main.js' ], output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, target: 'node', externals: nodeModules}这一步执行完,咱们失去一个合并后的文件bundle.js. 代码做混同这里抉择的工具是obfuscator,它和常见的UglifyJs不同,并非单纯的压缩,而是通过一系列的规定变换加大代码浏览剖析的难度。 这里介绍一些根本的规定: String Array 把字符串提取到独自的中央,真正应用的中央通过函数获取。 function hi() {  console.log("Hello World!");}hi(); // Rotate String Array 字符串程序随记,加大匹配难度var _0x520b = ['log', 'Hello\x20World!'];(function (_0x321927, _0x520b89) {    var _0x253eb2 = function (_0x3250e3) {        while (--_0x3250e3) {            _0x321927['push'](_0x321927['shift']());        }    };    _0x253eb2(++_0x520b89);}(_0x520b, 0x136));var _0x253e = function (_0x321927, _0x520b89) {    _0x321927 = _0x321927 - 0x0;    var _0x253eb2 = _0x520b[_0x321927];    return _0x253eb2;}; function hi() {    console[_0x253e('0x0')](_0x253e('0x1'));}hi(); // Encode String Literals 字符串做编码,这里应用RC4做转换var _0x483b = ['dKvj', 'Hello\x20World!'];(function (_0x385b34, _0x483bd9) {    var _0x4073b7 = function (_0x1c3313) {        while (--_0x1c3313) {            _0x385b34['push'](_0x385b34['shift']());        }    };    _0x4073b7(++_0x483bd9);}(_0x483b, 0x150));var _0x4073 = function (_0x385b34, _0x483bd9) {    _0x385b34 = _0x385b34 - 0x0;    var _0x4073b7 = _0x483b[_0x385b34];    return _0x4073b7;};var _0x1c33 = function (_0x385b34, _0x483bd9) {    _0x385b34 = _0x385b34 - 0x0;    var _0x4073b7 = _0x483b[_0x385b34];    if (_0x1c33['BHGvmm'] === undefined) {        var _0x1c3313 = function (_0xac223a) {            var _0x3f4880 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=',                _0x83de1c = String(_0xac223a)['replace'](/=+$/, '');            var _0x4991c2 = '';            for (var _0x3ba1df = 0x0, _0x1d9173, _0x26fc45, _0x2fff6e = 0x0; _0x26fc45 = _0x83de1c['charAt'](                    _0x2fff6e++); ~_0x26fc45 && (_0x1d9173 = _0x3ba1df % 0x4 ? _0x1d9173 * 0x40 + _0x26fc45 :                    _0x26fc45, _0x3ba1df++ % 0x4) ? _0x4991c2 += String['fromCharCode'](0xff & _0x1d9173 >> (-                    0x2 * _0x3ba1df & 0x6)) : 0x0) {                _0x26fc45 = _0x3f4880['indexOf'](_0x26fc45);            }            return _0x4991c2;        };        var _0x55c996 = function (_0x4e0902, _0x3315a6) {            var _0x3d0840 = [],                _0x3c70d0 = 0x0,                _0x26d9c2, _0x172d36 = '',                _0x161ef4 = '';            _0x4e0902 = _0x1c3313(_0x4e0902);            for (var _0x5c3e1a = 0x0, _0x11c688 = _0x4e0902['length']; _0x5c3e1a < _0x11c688; _0x5c3e1a++) {                _0x161ef4 += '%' + ('00' + _0x4e0902['charCodeAt'](_0x5c3e1a)['toString'](0x10))['slice'](-0x2);            }            _0x4e0902 = decodeURIComponent(_0x161ef4);            var _0x5f0953;            for (_0x5f0953 = 0x0; _0x5f0953 < 0x100; _0x5f0953++) {                _0x3d0840[_0x5f0953] = _0x5f0953;            }            for (_0x5f0953 = 0x0; _0x5f0953 < 0x100; _0x5f0953++) {                _0x3c70d0 = (_0x3c70d0 + _0x3d0840[_0x5f0953] + _0x3315a6['charCodeAt'](_0x5f0953 % _0x3315a6[                    'length'])) % 0x100, _0x26d9c2 = _0x3d0840[_0x5f0953], _0x3d0840[_0x5f0953] = _0x3d0840[                    _0x3c70d0], _0x3d0840[_0x3c70d0] = _0x26d9c2;            }            _0x5f0953 = 0x0, _0x3c70d0 = 0x0;            for (var _0xb1ce1a = 0x0; _0xb1ce1a < _0x4e0902['length']; _0xb1ce1a++) {                _0x5f0953 = (_0x5f0953 + 0x1) % 0x100, _0x3c70d0 = (_0x3c70d0 + _0x3d0840[_0x5f0953]) % 0x100,                    _0x26d9c2 = _0x3d0840[_0x5f0953], _0x3d0840[_0x5f0953] = _0x3d0840[_0x3c70d0], _0x3d0840[                        _0x3c70d0] = _0x26d9c2, _0x172d36 += String['fromCharCode'](_0x4e0902['charCodeAt'](                        _0xb1ce1a) ^ _0x3d0840[(_0x3d0840[_0x5f0953] + _0x3d0840[_0x3c70d0]) % 0x100]);            }            return _0x172d36;        };        _0x1c33['ZYjgxJ'] = _0x55c996, _0x1c33['URmLaR'] = {}, _0x1c33['BHGvmm'] = !![];    }    var _0x230d58 = _0x1c33['URmLaR'][_0x385b34];    return _0x230d58 === undefined ? (_0x1c33['eUtsvR'] === undefined && (_0x1c33['eUtsvR'] = !![]), _0x4073b7 =            _0x1c33['ZYjgxJ'](_0x4073b7, _0x483bd9), _0x1c33['URmLaR'][_0x385b34] = _0x4073b7) : _0x4073b7 =        _0x230d58, _0x4073b7;}; function hi() {    console[_0x1c33('0x0', 'F9Su')](_0x4073('0x1'));}hi();Self Defending 如果尝试对生成的代码进行格式化或重命名,整段代码将无奈执行。 ...

October 30, 2020 · 3 min · jiezi

关于node.js:nodejs篇http缓存

缓存是一种保留资源正本并在下次申请时间接应用该正本的技术,通过复用以前获取的资源,能够显着进步网站性能,升高服务器解决压力,缩小了等待时间和网络流量。通过应用 HTTP缓存,变得更加响应性。这篇文章会介绍三种缓存机制在nodejs中的实现,别离是: 强制缓存 Cache-Control/Expires比照缓存 Last-Modified/If-Modified-SinceEtag/If-None-Match两类缓存规定的不同强制缓存如果失效,不须要再和服务器产生交互,比照缓存不论是否失效,都须要与服务端产生交互。强制缓存优先级高于比照缓存,强制缓存失效时,不再执行比照缓存规定。新建http服务为了不便测试,新建一个简略的http服务进行调试: const http = require("http")const url = require("url")const mime = require("mime")const fs = require("fs")const server = http.createServer((req, res) => { const { pathname } = url.parse(req.url, true) const abspath = process.cwd() + pathname fs.stat(abspath, handleRequest) // 判断是文件还是文件夹 function handleRequest(err, statObj) { if (err || statObj.isDirectory()) return sendError(err) sendFile() } // 响应谬误申请 function sendError(error) { res.statusCode = 404 res.end(`Not Found \r\n ${error.toString()}`) } // 响应文件申请 function sendFile() { res.setHeader("Content-Type", mime.getType(abspath) + ";charset:utf-8") fs.createReadStream(abspath).pipe(res) }})server.listen(3000, () => console.log("serving http://127.0.0.1:3000"))强制缓存强制缓存指的是在缓存数据未生效的状况下,能够间接应用缓存数据,浏览器通过服务器响应的header获取缓存规定信息。对于强制缓存,响应头header应用Cache-Control/Expires来表明生效规定。 ...

October 29, 2020 · 2 min · jiezi

关于node.js:简单使用rabbitmq-和一些改进

炒鸡辣鸡说RabbitMQ不求甚解收取音讯 @Service@Slf4jpublic class RabbitMqMessage { private static final String EXCHANGE = "html"; private static final String CHECK_QUEUE = "check-queue"; @Autowired private DoCheckTask doCheckTask; @Bean private Declarables declarables() { Queue queue = new Queue(CHECK_QUEUE); FanoutExchange exchange = new FanoutExchange(EXCHANGE); return new Declarables(queue, exchange, BindingBuilder.bind(queue).to(exchange)); } @RabbitListener(queues = CHECK_QUEUE) public void receiverHtml(String urlContent) { UrlContent urlContent1 = Json.toObject(urlContent, UrlContent.class); doCheckTask.urlContentPriorityBlockingQueue.add(urlContent1); }}发送音讯 @Service@Slf4j@Configurationpublic class RabbitMqMessage { @Autowired private RabbitTemplate rabbitTemplate; /** * 页面内容播送交换机 */ private static final String HTML_EXCHANGE = "html"; @Bean public Declarables declarables() { FanoutExchange exchange = new FanoutExchange(HTML_EXCHANGE); return new Declarables(exchange); } public void sendHtmlToMessageQueue(String urlContent) { rabbitTemplate.convertAndSend(HTML_EXCHANGE, "", urlContent); }}简略来说,咱们只须要定义好消息队列的交换器和队列即可。交换器须要首先在你的治理页面中定义好。必不可少的是,咱们在配置文件中定义好连贯设置 ...

October 29, 2020 · 2 min · jiezi

关于node.js:volute-树莓派Nodejs造一个有灵魂的语音助手

volute 是什么?volute(蜗壳)是一个应用 Raspberry Pi+Node.js 制作的语音助手.什么是树莓派? 树莓派(英语:Raspberry Pi)是基于 Linux 的单片机电脑,由英国树莓派基金会开发,目标是以高价硬件及自由软件促成学校的根本计算机科学教育。 树莓派每一代均应用博通(Broadcom)出产的 ARM 架构处理器,现在生产的机型内存在 2GB 和 8GB 之间,次要应用 SD 卡或者 TF 卡作为存储媒体,装备 USB 接口、HDMI 的视频输入(反对声音输入)和 RCA 端子输入,内置 Ethernet/WLAN/Bluetooth 网络链接的形式(根据型号决定),并且可应用多种操作系统。产品线型号分为 A 型、B 型、Zero 型和 ComputeModule 计算卡。 简略的说,这是一台能够放到口袋里的电脑!!什么是 Node.js? Node.js 是一个能执行 Javascript 的环境,一个事件驱动 I/O 的 Javascript 环境,基于 Google 的 V8 引擎.什么是人机对话零碎 ? 人机对话(Human-Machine Conversation)是指让机器了解和使用自然语言实现人机通信的技术。对话零碎大抵可分为 5 个根本模块:语音辨认(ASR)、天然语音了解(NLU)、对话治理(DM)、自然语言生成(NLG)、语音合成(TTS)。 语音辨认(ASR):实现语音到文本的转换,将用户谈话的声音转化为语音。自然语言了解(NLU):实现对文本的语义解析,提取要害信息,进行用意辨认与实体辨认。对话治理(DM):负责对话状态保护、数据库查问、上下文治理等。自然语言生成(NLG):生成相应的自然语言文本。语音合成(TTS):将生成的文本转换为语音。资料筹备树莓派 4B 主板树莓派 5V3A TYPE C 接口微型 USB 麦克风迷你音箱16G TF 卡川宇读卡器杜邦线,外壳,散热片... 树莓派零碎装置及根底配置新的树莓派不像你买的 Macbook Pro 一样开机就能用 ????,想要顺利体验树莓派,还得一步一步来~ ...

October 26, 2020 · 6 min · jiezi

关于node.js:nodejs篇CommonJS加载模块分析

参考文章:CommonJS标准 剖析require 加载模块门路module.exports 导出模块~~~~每个模块都是一个沙箱环境,互不烦扰依据文件后缀判断文件解决形式(json,js)编写加载模块 requirefunction myRequire(moduleRelPath){ // 可能是相对路径,须要resolve path.resolve(__dirname,moduleRelPath);}Module 类模块function Module(moduleAbsPath){ this.modulePath = moduleAbsPath; this.exports = {}}拼接执行字符串Module.wrapper = [ "(function(exports,module,require){","})"]按文件解决Module.extension = { ".js"(module){}, ".json"(module){},}加载模块Module.prototype.load = function () { // 获取文件后缀名 let extname = path.extname(this.modulePath); // 交给对应办法解决 Module.extension[extname](this);};导出function myRequire(id) { let absPath = path.resolve(__dirname, id); let module = new Module(absPath); // 加载模块 module.load(); // 导出 return module.exports;}解析文件解决jsonModule._extensions[".json"] = (module)=> { let str = fs.readFileSync(module.id, "utf-8"); str = JSON.parse(str); // 取出内容间接绑定到 module.exports module.exports = str;}解决jsconst vm = require("vm");Module._extensions[".js"] = (module)=> { let str = fs.readFileSync(module.id, "utf-8"); // 拼接办法 let scriptStr = Module.wrapper[0] + str + Module.wrapper[1]; // 沙箱环境 let fn = vm.runInThisContext(scriptStr); // 执行并传参 fn.call(module.exports, module.exports, module, myRequire);}

October 23, 2020 · 1 min · jiezi

关于node.js:用-puppeteer-模拟人工实现网盘链接批量转存

需要剖析他人分享了很多网盘链接,本人每个手动去转存很浪费时间,而且,这些操作都是重复性劳动。与Pandownload的这个性能相似,不过pandownload因为一些起因无奈应用了,所以只能本人实现。 思路思路其实很简略,就是齐全模仿人为操作,将网盘链接存起来。咱们能够把网盘链接分为两种,第一种是没有提取码的,第二种是有提取码的。前者比后者少一个提交提取码的步骤。那么,咱们 如何辨别,拜访一个网盘链接的时候,到底是哪种呢?能够通过拜访页面的title来决定。这种是无提取码的,后缀是无限度这种是须要填写提取码的,后缀是请输出提取码,写代码的时候,截取后三个字儿提取码即可 填写Cookie信息批量转存的前提是,咱们得登录,我这里实现的计划是间接从浏览器中获取到cookie信息,复制到代码中进行应用,查看网站的cookie信息能够用插件EditThisCookie点击右上角导出Cookie,cookie就放在粘贴板中了,复制到代码中,而后应用循环,将所有cookie利用page.setCookie办法,将cookie搁置到以后申请上下文中 填写提取码期待页面加载结束,找到输出提取码框的元素,找到其id,而后应用page.$$eval()办法获取并写入货色能够看见,这里的id为accessCode。所以咱们只须要写 await page.$$eval('#accessCode', writeCode, code);async function writeCode(nodes, code) { for (let node of nodes) { node.value = code; }}就能够了。我这里是间接改的node.value,你也能够用puppeteer模仿人来填写。 提取文件找到提取文件按钮,点击,而后期待跳转结束。值得注意的是,咱们点击的肯定是A标签,其余标签须要进行过滤。 await page.$$eval('.g-button-blue-large', click);await page.waitFor(1000);async function click(nodes) { for (let node of nodes) { if (node.title === '提取文件') { await node.click(); } }}而后期待跳转即可 抉择要保留的文件这里简略实现为,抉择全副文件,不过值得注意的是,如果是单文件,是不须要点击抉择全副文件的。能够通过判断元素是否存在判断是否有复选框,是否须要进行点击如图,不过这里奇怪的是,class的值是一个不可读的字符串,我不确定这个值是不是与用户无关,所以这里就打码了。既然须要做的就是找到这个元素,点击就行了,那咱们照着做就行 await page.$$eval('.zbyDdwb', selectAll);async function selectAll(nodes) { for (let node of nodes) { await node.click(); break; }}点击保留到网盘与点击提取文件一样,找到目表按钮,而后点击就行,感兴趣的敌人,能够本人试试 弹出框抉择保留的文件门路防止麻烦,这里写得比较简单,如果有抉择跟上一次样的框,那么就点击抉择跟上一次一样,如果没有,就间接存储在根目录下。(能够依据你想要的需要本人改)抉择前抉择后能够发现,仅仅是扭转了Class的值,所以实现的时候,也扭转一下值就行 await page.$$eval('.save-path-item', chooseLocation);async function chooseLocation(nodes) { for (let node of nodes) { node.setAttribute('class', 'save-path-item check'); }}点击确定按钮与之前几个按钮一样,咱们只须要找到确认按钮,点击就行了。 ...

October 23, 2020 · 3 min · jiezi

关于node.js:使用fs模块批量重命名文件

话不多说,间接上个代码: 思路:应用fs模块,调用readdir()办法,读取指定目录下的文件,取得文件名数组后,循环,用正则表达式验证以后文件名是否含有须要替换的字符,如果有,就调用rename()办法,进行重命名操作。

October 22, 2020 · 1 min · jiezi

关于node.js:nodejs按行读取文件和写入文件的demo

一门后端语言,必不可少的就是须要跟文件系统进行交互。nodejs尽管是js的衍生物,然而必不可少的,也须要和文件系统进行交互。 nodejs写入文件const fs = require('fs');( ()=>{ for (let i = 0;i<100;i++){ fs.writeFile("D:\\workspace\\node\\check\\bbs\\controllers\\1.txt","123",{ flag:'a' },function (err) { if (err !== null) { console.log(err) } }); } fs.close();})();如果环境中没有fs模块,应用npm装置即可 nodejs按行读取文件const readline = require('readline');const fs = require('fs');( () => { let fRead = fs.createReadStream("D:\\workspace\\node\\check\\bbs\\controllers\\1.txt"); let objReadLine = readline.createInterface({ input: fRead }); objReadLine.on('line', function (line) { console.log('urlTrue=',line); });})();炒鸡辣鸡原创文章,转载请注明起源

October 22, 2020 · 1 min · jiezi

关于node.js:Nodejs-15-正式版发布

前两天,Node.js官网公布了Node.js 15的正式版本,Node.js 15 将代替 Node.js 14 成为以后的的稳固发行版,后者将在本月晚些时候降级为 LTS(长期反对)版本。如果大家想体验下Node.js 15 的最新性能,能够从官网进行下载。 那Node.js 15带来了哪些新的性能和个性呢?次要体现在以下几个方面: AbortControllerN-API 版本 7npm 7unhandled rejections 默认抛出QUICV8 8.6AbortControllerAbortController接口示意一个控制器对象,容许开发者依据须要停止一个或多个 Web申请,Node.js 15 退出了 AbortController 的一个实验性实现。AbortController 是一个全局实用工具类,可依据 AbortController Web API在选定的基于 Promise 的 API 中勾销收回的申请信号,如下所示。 const ac = new AbortController();ac.signal.addEventListener('abort', () => console.log('Aborted!'),{ once: true });ac.abort();console.log(ac.signal.aborted); //Prints True在下面的示例中,当调用 abortController.abort()办法时就会收回 abort 事件,AbortController 将仅触发一次 abort 事件。同时,附加到 AbortSignal 上的事件侦听器应应用{ once: true}参数选项(或等效于 EventEmitterAPI 的 once()),以确保一旦 abort 事件失去解决,而后再将事件侦听器删除。 对于AbortController的 Node.js API 文档,能够参考:AbortController。 N-API 7N-API是一个用于构建本机插件的API,它独立于底层JavaScript运行时环境(如V8),并作为Node.js自身的一部分。此API将作为跨Node.js版本已编译的利用程序接口(Application Binary Interface)的稳定版,简称(ABI)。它是为了将Addons插件和底层JavaScript引擎的改变隔离开来,并且容许在一个版本编译的模块不须要从新编译就能够在更高版本的Node.js上运行。 ...

October 22, 2020 · 3 min · jiezi

关于node.js:客户端安全相关知识点

攻打的目标 获得在线敏感数据和敏感操作利用客户的浏览器执行js做提交或者获得cookie认证实质 获得认证:Cookie 影响Cookie认证信息的几个重要属性 Domain:向哪些域发送本cookiePath:向哪些门路发送本cookieSecure:向非ssl服务发送本cookieHttponly:利用javascript获取本cookieP3p:当页面作为iframe等html标签嵌入时,ie是否承受并且发送本cookie影响客户端发送或者获取数据的Domain同源策略 客户端脚本的安全性规范同协定,同域名,同端口获得操作数据的权限:ajax/csrfP3p应答计划 从架构上解决问题 设计时须要思考的 咱们的Cookie认证信息真的须要设置到整个域么不同安全级别的服务能够放到一个域下么前台和后盾在安全等级上是离开的,真的离开了么咱们重要的业务真的曾经独立开来了么解决 认证cookie和应用程序cookie独立开(爱护认证)Httponly(放到哪个域名)应用程序后盾敏感操作和前台操作域名独立(同源策略)慎用p3pXSS进攻计划 过滤输出中的特殊符号辨别富文本和非富文本,encode非富文本对富文本开始做语法树剖析增强表单验证……从设计上解决问题 信赖域的划分是平安设计的根底拜访控制系统是平安设计的外围数据与代码拆散是平安设计的体现白名单与不可预测性是平安设计的保障炒鸡辣鸡原创文章,转载请注明起源

October 22, 2020 · 1 min · jiezi

关于node.js:构建内网安全的威胁与方法

网络钓鱼窍门 选好钓位,选准诱饵,备好钓具,练好钓具行为特色 各式各样的坑骗邮件带附件老本 工夫和急躁0Day,不愿也上钩人肉办法 无线网络攻打 窃取接入明码流氓AP攻打间接物理攻击 胜利应聘某个岗位,间接攻打企业外部老本 物理上靠近指标器材应答办法 管好无线 Radius 证书 双因素 隔离 无线用户应用独立的网络,不接入办公网Client lsolation避免流氓AP 员工擅自装置的AP:禁止装置黑客装置的AP(airsnarf):隔离做好应聘人员背景考察浸透黑客思路:在扎根、扩充权限的同时找货色攻击方式 扫描端口,破绽,弱明码和共享破解明码并尝试登陆装置不同的后门网络坑骗攻打老本 工具:扫描,数据分析,文件查找,明码破解,后门工夫:太快容易被发现,太慢也容易被发现应答办法 应答扫描和明码破解 Ip地址一对多,目标端口绝对固定数据包行为短时间内大量反复后门 后门的分类和部署形式 按公开水平分:公有、小范畴公开和齐全公开公有、小范畴公开和齐全公开按协定分:UDP TCP ICMP FTP SMTP HTTP按行为分:正连(被动)和 回连(被动)按性质分:干活用,尽量不便;回生用,尽量荫蔽。BIOS,疏导区公开公有混合部署,多种协定混合部署;正连回连混合部署;大量干活,大量回生检测后门 行为检测协定特色监控响应应答坑骗 坑骗的类型 ARP坑骗:MAC-IPCAM坑骗:MAC-PORT行为特色 大量ARP包元素对应关系变动频繁应答办法 Arp监控Cisco Port Security.•划VLAN禁共享,监控扫描、破解、坑骗和后门收货行为剖析 收货:黑客从办公网下载数据的过程收货的形式 用后门间接下载用邮件发送联合包转发程序用HTTP/FT[+Socks多线程下载(HTran)行为特色 超长连贯Socks4/5协定继续大量PSH-ACK应答收货 Panabit 监控主机流入流出的流量监控长连贯、Socks和上传流量炒鸡辣鸡原创文章,转载请注明起源

October 22, 2020 · 1 min · jiezi

关于node.js:ERROR-Please-install-mysql2-package-manually

ERROR: Please install mysql2 package manually当装置和应用sequelize 呈现这个问题时1.可能没有装置mysql2 包解决办法: yarn add mysql2 2.可能是webpack无奈辨认解决办法: yarn add webpack-node-externals 在webpack.config.js 中 增加:const nodeExternals = require('webpack-node-externals')module.exports = { ... externals: [nodeExternals()]}即可 webpack 内部扩大(externals)

October 21, 2020 · 1 min · jiezi

关于node.js:传统后端开发者视角学习异步Nodejs的血泪笔记

之前始终以传统后端的思维来写nodejs的代码,发现运行后果与我的同步思维形式不太一样,所以须要全面将nodejs学习一下。此学习笔记适宜后端同学学习nodejs的时候观看,前端大佬能够多多斧正。 环境变量console.log(setTimeout);console.log(setInterval);console.log(setImmediate);console.log(__filename); // 以后文件的全名console.log(__dirname); //console.log(process); // 过程信息,全局变量process就是以后运行环境变量的集合体。例如process.argv就是获取用户输出的参数 数学库与Java一样,叫Math Math.random(); // 返回0~1的浮点数模块标准之exports和module.exports的关系须要解决的问题: 脚本变多时,须要手动治理加载程序不同脚本之间逻辑调用,须要通过全局变量的形式去交换,例如:JQUERY。将输入放到全局变量中,而后由其余局部进行应用没有html怎么办?nodejs中应用CommonJs模块标准,加载另一个js,用require函数来获取即可。 // demo.jsconsole.log("-----------");let lib = require('./lib');console.log('---------',lib);// lib.jsconsole.log('==========');exports.hello = '++++++++++';exports.word = '///////////////';exports.add = function () { console.log('1111111111111')};能够看见,模块中定义模块输入的形式:默认会注入一个叫export的变量,在该变量上挂参数就相当于给以后被require对象外面附一个值。还能够挂函数,对象等,实践上就是在输入对象中加对象。所以在exports中咱们能够挂各种类型的构造同时,对于exports来说,里面能够扭转模块外面的内容,是同一个援用。 // demo.jsconsole.log("-----------");let lib = require('./lib');lib.addd = '*******************';console.log('---------',lib);// lib.jsconsole.log('==========');exports.hello = '++++++++++';exports.word = '///////////////';exports.add = function () { console.log('1111111111111')};setTimeout(()=>{ console.log(exports)},2000);运行后果如下,能够看见批改了里面被require的对象,外面的exports对象也被批改了 特定地,如果心愿被require进去的不是一个对象,而是一个办法,或者变量啥的,能够应用module.exports,然而会笼罩掉之前怼exports变量的批改。 // demo.jsconsole.log("-----------");let lib = require('./lib');console.log('---------',lib);// lib.jsconsole.log('==========');exports.hello = '++++++++++';exports.word = '///////////////';exports.add = function () { console.log('1111111111111')};module.exports = function dsa() { return '123'};最终打印的后果为能够看到后果中exports变量的值并没有被输入进去,失去这样的后果有两种可能性,第一是module.exports将exports对象给笼罩掉了,第二种是module.exports和exports在文件被require的时候其实是两个不同的货色,指向两个不同的内存,当模块被require的时候,如果module.exports没有被指定,那么就require进去的是exports对象,如果module.exports被指定了,那么就应用module,exports。我比拟偏向于前面这种解释,上面来证实我的观点。 ...

October 21, 2020 · 1 min · jiezi

关于node.js:nodejs使用Sequelize框架操作数据库

sequelize.define应用该办法能够定义model,例子如下: const Sequelize = require('sequelize');var sequelize = new Sequelize(config.database, config.username, config.password, { host: config.host, dialect: 'mysql', pool: { max: 5, min: 0, idle: 30000 }});var Website = sequelize.define('website', { id: { type: Sequelize.BIGINT, primaryKey: true, autoIncrement: true }, url: Sequelize.STRING(255), title: Sequelize.STRING(255), status: Sequelize.INTEGER, delete_mark: Sequelize.BOOLEAN}, { timestamps: false});该办法传入的第一个参数是数据表的复数模式,怎么了解呢?例如这里传入的是website其实是模型名,数据表默认是websites这样的复数模式,这种约定我在Laravel中也碰见过,也就是常说的,约定大于定义,也就是说,如果咱们都依照约定的标准去开发,那么效率其实比从新定义,要高很多。那么,定义好了模型,该怎么进行应用呢? (async () => { let demo = await Website.create({ url:'http://www.xxxx.com/', title:'demo' }); console.log(demo);})();继承Modelconst {Sequelize, DataTypes, Model} = require('sequelize');const config = require('../config');const sequelize = new Sequelize(config.database, config.username, config.password, { host: config.host, dialect: 'mysql', pool: { max: 5, min: 0, idle: 30000 }});/** * @author chaojilaji * 数据表websites的关系对象映射 */class WebSite extends Model {}WebSite.init({ id: { type: Sequelize.BIGINT, primaryKey: true, autoIncrement: true }, url: Sequelize.STRING(255), title: Sequelize.STRING(255), status: Sequelize.INTEGER, delete_mark: Sequelize.BOOLEAN}, { sequelize, modelName: 'Website', timestamps:false});(async () => { await sequelize.sync(); let x = await WebSite.create({ url: 'http://www.xxxxxxxx.com/', title: 'demo2' }); console.log(x);})();module.exports = WebSite;我比拟举荐应用继承Model这种形式,通过创立一个class,这样能够应用model.exports=模块名的形式,将该模型封装起来。供别的中央应用,只须要require进去即可。 ...

October 20, 2020 · 1 min · jiezi

关于node.js:node实用工具库

命令行minimist 解析命令行选项的库

October 20, 2020 · 1 min · jiezi

关于node.js:可能是目前最强大的开源在线表格不信你来看看

当初在线的办公套件应用频率越来越高,不论是国外的 Google 办公套件还是国内的石墨文档,金山文档等,都是很优良的产品。开源畛域里也有不少优良的在线表格开源我的项目,那么明天所举荐的 Luckysheet 到底有什么不同之处呢?那就持续往下看看吧。 项目名称: Luckysheet 我的项目作者: mengshukeji 开源许可协定: MIT 我的项目地址:https://gitee.com/mengshukeji/Luckysheet 我的项目简介Luckysheet 是一款纯前端相似 Excel 的在线表格,功能强大、配置简略、齐全开源。 Luckysheet 独有个性矩阵计算 (通过右键菜单进行反对:对选区内的数据进行转置、旋转、数值计算) 截图 (把选区的内容进行截图展现) 复制到其余格局 (右键菜单的"复制为", 反对复制为json、array、对角线数据、去重等) EXCEL,CSV,TXT 导入及导出 (专为Luckysheet打造的导入导出插件,反对明码、水印、公式等的本地导入导出)插入图片和svg形态 (反对JPG,PNG,SVG,Pen tool的插入、批改和删除,并且随表格的变动而产生变动) 数据验证(表单性能) (反对Checkbox, drop-down list, datePicker) 单元格内多样式 (Alt+Enter单元格内换行、上标、下标、单元格内可定义每个文字的不同款式) 其余个性除了最根本的表格性能,Luckysheet 还有如下几个值得关注的个性。 公式和函数内置公式数学 (SUMIFS, AVERAGEIFS, SUMIF, SUM, etc.)文本 (CONCATENATE, REGEXMATCH, MID)日期 (DATEVALUE, DATEDIF, NOW, WEEKDAY, etc.)财务 (PV, FV, IRR, NPV, etc.)逻辑 (IF, AND, OR, IFERROR, etc.)查找和援用 (VLOOKUP, HLOOkUP, INDIRECT, OFFSET, etc.)动静数组 (Excel2019新函数,SORT,FILTER,UNIQUE,RANDARRAY,SEQUENCE)公式反对数组 (={1,2,3,4,5,6}, Crtl+Shift+Enter)近程公式 (DM_TEXT_TFIDF, DM_TEXT_TEXTRANK,DATA_CN_STOCK_CLOSE etc. Need remote interface, can realize complex calculation)自定义公式 (依据身份证辨认年龄,性别,生日,省份,城市等. AGE_BY_IDCARD, SEX_BY_IDCARD, BIRTHDAY_BY_IDCARD, PROVINCE_BY_IDCARD, CITY_BY_IDCARD, etc. 能够任意退出本人的公式哦)数据透视表字段拖拽 (操作形式与excel相似,拖动字段到行、列、数值、筛选等4个区域)聚合形式 (反对汇总、计数、去重计数、均匀、最大、最小、中位数、协方差、标准差、方差等计算)筛选数据 (可对字段进行筛选后再进行汇总)数据透视表下钻 (双击数据透视表中的数据,能够下钻查看到明细,操作形式与excel统一)依据数据透视表新建图表 (数据透视表产生的数据也能够进行图表的制作)图表反对的图表类型 (目前折线图、柱状图、面积图、条形图、饼图能够应用,散点图、雷达图、仪表盘、漏斗图正在接入,其余图表正在陆续开发中,请大家给予倡议)对于图表插件 (图表应用了一个两头插件ChartMix(MIT协定): 目前反对ECharts,正在逐渐接入Highcharts、阿里G2、amCharts、googleChart、chart.js)Sparklines小图 (以公式的模式进行设置和展现,目前反对:折线图、面积图、柱状图、累积图、条形图、离散图、三态图、饼图、箱线图等)开发环境Node.js Version >= 6 ...

October 19, 2020 · 1 min · jiezi

关于node.js:redis缓存

pom.xml文件<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId></dependency>在测试类测试 jedis.setex(key,存活工夫,v)jedis.setnx(k,?)如果k里没有值就赋值,有就不动。 秒杀业务的实现--分布式锁机制7000元 手机 20显示胜利 领取1元首先:1tomcat服务器必定有多台 2数据库数据只有1份 3 必然会呈现高并发的景象 即多线程对同一资源进行操作,导致线程安全性问题 应用同步锁:实用于单台tomcat服务器 同步锁不适用于大程序的开发,因为它只能负责体态tomcat ![image.png](/img/bVcHorV)如果两台tomcat都应用同步锁, 两台服务器独特对数据库进行读写操作,肯定会产生并发问题,即手机屡次卖出。怎么保障业务的实现?? 为了解决这种问题时用分布式锁,锁应用第三方操作,专用。 准则:当锁被应用时,其余用户不能应用。策略:用户向redis中放弃一个key,如果redis中有人应用这把锁,其他人不容许应用。如果redis没有key,则示意我能够应用这把锁。为了避免这个key始终不开释就在锁设置存活工夫。 原理图 用的是一个redisredis单线程,单过程的,所以不会有同时存key的可能加锁 setkey解锁 delkey具体如何验证加锁胜利jedis.set("aaa",v,setParams)这个办法里,如果加锁胜利会返回ok 解锁还会呈现一个问题,因为解锁的办法都在finally外面,所以他人可能会接调属于本人的锁,造成了提前开释。所以须要设定明码,就value。真正的明码匹配或者是超出了执行工夫才会开释。

October 17, 2020 · 1 min · jiezi

关于node.js:如何将Nodejs-Docker镜像大小减小10倍

对应用程序进行Docker化非常简单,无效,然而优化Docker Image的大小是辣手的局部。 Docker易于应用,然而一旦应用程序开始扩大,镜像大小就会呈指数增长。通常,大多数状况下,应用程序的Node.js docker镜像大小超过1 GB。 为什么镜像大小很重要较大的docker镜像须要更多空间,这意味着减少费用。较长的构建工夫-将镜像通过网络推送会破费更长的工夫,并导致CI管道提早。让咱们开始优化这是应用VueJS应用程序构建的演示应用程序。 这是初始的Dockerfile。 FROM node:10WORKDIR /appCOPY . /appEXPOSE 8080RUN npm install http-server -gRUN npm install && npm run buildCMD http-server ./dist该镜像的大小为1.34GB: 让咱们开始逐渐优化。 1:应用多阶段Docker构建 多阶段构建可通过在单个Dockerfile中应用多个两头镜像来轻松优化Docker镜像。在此处理解更多信息。通过应用多阶段构建,咱们能够在构建镜像中装置所有依赖项,并将它们复制到精简运行时镜像中。 FROM node:10 AS BUILD_IMAGEWORKDIR /appCOPY . /appEXPOSE 8080RUN npm install && npm run buildFROM node:10WORKDIR /app# copy from build imageCOPY --from=BUILD_IMAGE /app/dist ./distCOPY --from=BUILD_IMAGE /app/node_modules ./node_modulesRUN npm i -g http-serverCMD http-server ./dist当初,此镜像的大小为1.24GB: 2:删除开发依赖项并应用 Node Prune 工具 ...

October 12, 2020 · 1 min · jiezi

关于node.js:多个你不知道的-CSS-居中方案

作者: Ahmad Shadeed 译者:前端小智起源:ishadeed挪动端浏览:https://mp.weixin.qq.com/s/kp...点赞再看,养成习惯本文 GitHub https://github.com/qq44924588... 上曾经收录,更多往期高赞文章的分类,也整顿了很多我的文档,和教程材料。欢送Star和欠缺,大家面试能够参照考点温习,心愿咱们一起有点货色。 大家都说简历没我的项目写,我就帮大家找了一个我的项目,还附赠【搭建教程】。 程度居中内联元素要使内联元素(如链接,span 或img)居中,应用 text-align: center 足够了。 <div class="desk"> <span class="plate"></span></div>.desk { text-align: center;} 对于多个内联元素,也能够应用text-align:center: <div class="desk"> <span class="plate"></span> <span class="plate"></span></div>.desk { text-align: center;} Flexbox应用 flexbox 也能够疾速居中元素: .desk { display: flex; justify-content: center;}对于多个内联的我的项目,也能够失常工作: CSS Grid应用网格容器时,图中的盘子将依据其网格区域居中。 请留神,除非将它们包裹在一个元素中,否则这将不适用于多个盘子。 .desk { display: grid; justify-content: center;} 块元素Auto Margin宽度和高度已知的块元素能够通过设置margin-left:auto 和 margin-right:auto 居中元素。 .plate { width: 120px; height: 120px; margin-left: auto; margin-right: auto;} 对于多个块元素,它们应该包装在一个元素中,而后让这个父元素居中。 .tray { display: flex; margin-left: auto; margin-right: auto;} ...

October 12, 2020 · 1 min · jiezi

关于node.js:一套成熟的BPM系统应该有的功能

BPM 业务流程管理系统 前言 近几年IT行业各种IT利用倒退非常迅猛,企业和公司外部信息管理系统越来越多。因为一些起因,这些零碎的信息资源管理扩散、共享艰难、由此造成了一些信息孤岛。当初越来越多的企业要求数据集中、对立、智能化治理,所以如何科学管理和正当开发这些信息系统,成了目前公司以及一些IT公司面临的微小难题。 BPM能解决什么问题 帮忙进步外围业务流程的有效性和效率 帮忙晋升整体灵活性以进行疾速交付,并能够适应各种业务流程下面的变动。 那有的BPM框架应该具体哪些性能 1、业务流程治理核心(process center): 能对立治理各类业务流程、服务以及各种适配器 能对立实现业务流程的测试、模仿、部署、运行、监控、改良、变更 能做到业务流程治理核心治理着所有的业务流程的各个历史版本。 2、业务流程运行环境(Process Server) 以全面的解耦业务流程各个方面的逻辑局部,造成模式涣散、无缝集成、动静可配置的运行环境。 3、业务流程设计器(Process Designer) 业务流程设计器必须反对可视化的仿真、剖析与优化。 业务流程设计器必须反对所见即所得的实时回放,即编辑完业务流程之后,毋庸任何 IT 人员的帮助和期待 IT 开发 4、业务集成设计器(Integration Designer) 反对基于 SOA 的服务 次要性能简介

October 10, 2020 · 1 min · jiezi

关于node.js:node

为什么要学习node.js可能和后端程序员更加严密的配合可能扩宽本人的常识视线学习前端常识须要后端常识的撑持(ajax)node开发须要做的事件实现网站的业务逻辑实现数据的增删改查为什么抉择node应用javascript语法开发后端利用一些公司要求前端工程师必须要把握node开发生态系统沉闷,有大量开源库能够应用前端开发工具大多都是基于node开发为什么要应用node开发呢node是基于chrome v8引擎的javascript代码运行环境windows及liux装置node.js的办法。windows装置node.js的办法:https://www.cnblogs.com/liuqi...liux装置node.js的办法:https://segmentfault.com/a/11...

October 5, 2020 · 1 min · jiezi

关于node.js:Deepin-v20安装node及npm

1.下载node.jsnode官网: https://nodejs.org/en/,并将下载好的node压缩包解压并改名为node 2.解锁文件夹应用sudo chmod -R 777 文件夹的命令解锁usr下的local文件夹3.挪动node文件夹至local目录下 4.创立软连贯实现全局调用将下列代码在终端输出即可 sudo ln -s /usr/local/node/bin/node /usr/local/bin/sudo ln -s /usr/local/node/bin/npm /usr/local/bin/5.查看版本node -v:查看node.js的版本npm -v:查看npm的版本

October 4, 2020 · 1 min · jiezi

关于node.js:Node开发神器使用Llama-Logs实时可视化Node错误

原文:https://dev.to/bakenator作者:bakenator你是否想晓得程序外部产生了什么?是否心愿以视觉形式查看其外部运作? 下面的动图显示了Llama Logs的一个例子。它是我创立的一个新工具,让你实时看到你的应用程序的外部运作。它曾经筹备好了,你能够开始在你的应用程序中收费应用。 上面,我将通过一个示例演示如何应用Llama Logs显示和调试根本Express应用程序中产生的谬误。 开始我将编写一个根本的疾速应用程序,该应用程序通过url参数接管用户的电子邮件,如果该电子邮件是 llamalogs.com 域,则将其保留到数据库中。 根本逻辑将如下所示 app.get('/', (req, res) => { let customerEmail = req.query.email let isDomainOk = domainCheck(customerEmail) if (isDomainOk) { saveEmail(customerEmail) } res.send('We received your email')})当初的问题是,我要写一些查看的代码,如果用户遗记在邮件中蕴含 @domain 局部,就会出错。 const domainCheck = (customerEmail) => { // toLowerCase will fail if the [1] value is undefined! const domain = customerEmail.split("@")[1].toLowerCase() const domainIsOk = domain === "llamalogs.com" return domainIsOk}应用Llama Logs进行可视化Llama Logs的设置非常简单。一旦你注册了llamalogs.com,你所须要做的就是通过npm装置客户端,而后开始而后开始记录,Llama Logs将主动将你的日志转换为交互式图形。 因而,例如,让咱们将 domainCheck 办法更新为以下内容 ...

October 2, 2020 · 2 min · jiezi

关于node.js:NodeJs-与最佳实践译

文章首发于我的博客 https://github.com/mcuking/bl...译者:最近在钻研前端架构分层,在 medium 看到了这篇对于 node.js 架构分层的文章,感觉很不错,顺便翻译过去分享给大家,其中很多思维也能够利用到前端我的项目中。 原文链接 https://blog.codeminer42.com/... 软件随时可能更改,而定义代码品质的一个方面就是更改代码的难易水平。然而是什么使它是这样的? ...如果您胆怯扭转某些货色,显然是设计得不好。 —马丁·福勒关注点和职责拆散“将因为雷同起因而发生变化的事物汇集在一起。离开那些因不同起因而扭转的事物。”无论是性能,类还是模块,它们都能够利用于繁多职责准则和关注点拆散 the single responsibility principle and the separation of concerns。基于这些原理进行设计软件架构。## 架构在软件开发中,职责是团结一致要实现的工作,例如:在应用程序中示意产品的概念,解决网络申请,将用户保留在数据库中等等。您是否留神到这三个职责不在同一类别中?这是因为它们属于不同的层,因而又能够分为概念。依据下面的示例,“在数据库中保留用户”与“用户”概念无关,也与数据库进行通信的层无关。通常,与上述概念相干的体系结构偏向于分为四层:domain, application, infrastructure, input interfaces。## Domain 层在这一层中,咱们能够定义充当实体和业务规定的角色并与咱们的 domain 有间接关系的单元。例如,在用户和团队的应用程序中,咱们可能会有一个 User 实体,一个 Team 实体和一个 JoinTeamPolicy 来答复用户是否可能退出给定的团队。这是咱们软件中最孤立最重要的层,Application 层能够应用它来定义用例。## Application 层Application 层定义了咱们应用程序的理论行为,因而负责执行 domain 层各单元之间的交互。例如,咱们能够有一个 JoinTeam 用例,该用例接管 User 和 Team 的实例,并将它们传递给 JoinTeamPolicy。如果用户能够退出,它将长久化职责委托给 infrastructure 层。Application 层也能够用作 infrastructure 层的适配器。假如咱们的应用程序能够发送电子邮件;间接负责与电子邮件服务器通信的类(称为 MailChimpService)属于 infrastructure 层,然而理论发送电子邮件的电子邮件(EmailService)属于 application 层,并在外部应用 MailChimpService。因而,咱们的应用程序的其余部分不晓得无关特定实现的详细信息-它仅晓得 EmailService 可能发送电子邮件。## Infrastructure 层这是所有层中的最低层,它是应用程序内部的边界:数据库,电子邮件服务,队列引擎等。多层应用程序的一个独特特色是应用 repository pattern 与数据库或其余一些内部长久化服务(例如 API)进行通信。Repository 对象实质上被视为汇合,应用它们的层(domain 和 application)不须要晓得底层的长久化技术(相似于咱们的电子邮件服务示例)。这里的想法是,repository 接口属于 domain 层,而实现又属于 infrastructure 层,即 domain 层仅晓得 repository 承受的办法和参数。即便在测试方面,这也使两层都更加灵便!因为 JavaScript 并未实现接口的概念,因而咱们能够设想本人的接口,并以此为根底在 infrastructure 层上创立具体的实现。## Input interfaces 层该层蕴含应用程序的所有入口点,例如控制器,CLI,websocket,图形用户界面(如果是桌面应用程序)等等。它应该不具备无关业务规定、用例、长久化技术的常识,甚至不具备其余逻辑的常识!它应该只接管用户输出(如 URL 参数),将其传递给用例,最初将响应返回给用户。## NodeJS 与关注点拆散好了,通过所有这些实践之后,它如何在 Node 应用程序上工作?说实话,多层体系结构中应用的某些模式非常适合 JavaScript 世界!## NodeJS 和 domain 层Node 上的 domain 层能够由简略的 ES6 classes 组成。有许多 ES5 和 ES6 +模块可帮忙创立实体,例如:Structure, Ampersand State, tcomb 和 ObjectModel。让咱们看一个应用 Structure 的简略示例:`jsconst { attributes } = require('structure');const User = attributes({ id: Number, name: { type: String, required: true }, age: Number})( class User { isLegal() { return this.age >= User.MIN_LEGAL_AGE; } });User.MIN_LEGAL_AGE = 21;`请留神,咱们的列表中不蕴含 Backbone.Model 或 Sequelize 和 Mongoose 之类的模块,因为它们打算在 infrastructure 层中用于与内部世界进行通信。因而,咱们代码库的其余部分甚至不须要理解它们的存在。## NodeJS 与 application 层用例属于 application 层,与 promises 不同,用例可能会带来胜利与失败之外的后果。对于这种状况,比拟好的 Node 模式是 event emitter。要应用它,咱们必须扩大 EventEmitter 类并为每个可能的后果收回一个事件,从而暗藏了咱们的 repository 在外部应用了 promise 的事实:`jsconst EventEmitter = require('events');class CreateUser extends EventEmitter { constructor({ usersRepository }) { super(); this.usersRepository = usersRepository; } execute(userData) { const user = new User(userData); this.usersRepository .add(user) .then(newUser => { this.emit('SUCCESS', newUser); }) .catch(error => { if (error.message === 'ValidationError') { return this.emit('VALIDATION_ERROR', error); } this.emit('ERROR', error); }); }}`这样,咱们的入口点就能够执行用例并为每个后果增加一个监听器,如下所示:`jsconst UsersController = { create(req, res) { const createUser = new CreateUser({ usersRepository }); createUser .on('SUCCESS', user => { res.status(201).json(user); }) .on('VALIDATION_ERROR', error => { res.status(400).json({ type: 'ValidationError', details: error.details }); }) .on('ERROR', error => { res.sendStatus(500); }); createUser.execute(req.body.user); }};`## NodeJS 与 infrastructure 层infrastructure 层的实现不应很艰难,但要留神其逻辑不要透露到以上各层!例如咱们能够应用 Sequelize 模型来实现与 SQL 数据库进行通信的存储库,并为其提供办法名称,而这些名称并不暗示其下存在 SQL 层-例如咱们上一个示例的通用 add 办法。咱们能够实例化一个 SequelizeUsersRepository 并将其作为 usersRepository 变量传递给它的依赖项,这些依赖项可能只是与其接口交互。`jsclass SequelizeUsersRepository { add(user) { const { valid, errors } = user.validate(); if (!valid) { const error = new Error('ValidationError'); error.details = errors; return Promise.reject(error); } return UserModel.create(user.attributes).then(dbUser => dbUser.dataValues); }}`对于 NoSQL 数据库,电子邮件服务,队列引擎,内部 API 等,也是如此。## NodeJS 和 input interfaces 层在 Node 应用程序上实现此层有很多种形式。对于 HTTP 申请,Express 模块是应用最多的模块,但您也能够应用 Hapi 或 Restify。最终抉择取决于实现细节,只管对此层所做的更改不应影响其余细节。如果从 Express 迁徙到 Hapi 某种程度上意味着在要更改某些代码时,则示意已耦合,并且您应密切注意对其进行修复。## 连贯这些层间接与另一层进行通信可能是一个谬误的决定,并导致它们之间的耦合。在面向对象的编程中,解决此问题的常见办法是依赖注入 dependency injection(DI)。这种技术包含使类的依赖项在其构造函数中作为参数接管,而不是引入依赖项并将其实例化到类自身外部,从而创立了所谓的管制反转。应用这种技术使咱们可能以一种十分简洁的形式隔离一个类的依赖关系,使其更加灵便且易于测试,因为解决依赖关系成为一项琐碎的工作对于 Node 应用程序,有一个很好的 DI 模块,称为 Awilix,它使咱们可能在不将代码耦合到 DI 模块自身的状况下利用 DI,因而咱们不心愿应用 Angular 1 那种奇怪的依赖注入机制。Awilix 的作者有一系列的文章,它们解释了 Node 的依赖注入,值得一读,并且还介绍了如何应用 Awilix。顺便说一句,如果您打算应用 Express 或 Koa,还应该看看 Awilix-Express 或 Awilix-Koa。## 一个实际的例子即便有了所有这些无关层和概念的示例和阐明,我置信没有什么比遵循多层架构的应用程序的理论示例更好的了,这足以使您确信应用起来很简略!你能够查看可用在生产环境的 boilerplate for web APIs with Node。它采纳了多层架构,并曾经为您设置了根底配置(包含文档),因而您能够练习甚至将其用作 Node 应用程序的开始模板。## 额定信息如果您想理解无关多层架构以及如何拆散关注点的更多信息,请查看以下链接:- FourLayerArchitecture- Architecture — The Lost Years- The Clean Architecture- Hexagonal Architecture- Domain-driven design

September 30, 2020 · 2 min · jiezi

关于node.js:node的http与前端交互示例入门

一、目录(node_modules是npm install后新增的) node 和 npm 版本 npm install http 二、node下的index.js var http = require('http')http.createServer(function (request, response) { response.writeHead(200, { 'Content-Type': 'text/plain' }) request.on('data', function (chunk) { response.write(chunk) }) request.on('end', function () { response.end('hello node world') }) }).listen(8090)监听localhost的8090端口 三、前端home.html页面 <!DOCTYPE html><html><head> <title>node home</title></head><body> <script type="text/javascript"> window.onload = function () { var body = document.getElmentsByTagName('body')[0] var xhr = new XMLHttpRequest() xhr.open('GET', '/localhost:8090', false) xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.Status === 200) { body.innerHtml = xhr.responseText } } } </script></body></html>简略测试,间接应用了原生JavaScript的ajax,发送get申请到localhost:8090,返回后果输入到页面上 ...

September 30, 2020 · 1 min · jiezi

关于node.js:NodeJS-基于redis的分布式锁的实现Redlock算法

1. 前言开发时,碰到互斥问题,须要保障在分布式环境下,防止重复性操作批改用户状态,如:用户订单状态,购票时,批改票的余额等 2. 分布式锁的条件分布式锁须要满足下列条件 锁须要有短缺的可拜访的存储空间锁必须被惟一标识锁至多要有两种状态同时,要保障 平安个性:互斥拜访,永远只有一个client能拿到锁防止死锁:client最初能够拿到锁,不会呈现死锁,即便本来上锁的client呈现问题无奈解锁容错性:容错,只有大多数redis节点可能失常工作,客户端端都能获取和开释锁。3.Redis单节点上锁的实现应用下列语句获取一个不存在的key,如果能够已存在则创立失败,确保key值惟一, 加上过期工夫,确保零碎谬误后及时解锁,防止死锁 SET key value NX PX 30000然而这种办法在主库谬误时,会产生谬误,redis主从同步是异步,主库谬误时,从库若还没有锁的信息,则会导致多个过程持有锁 3. Redlock算法(官网文档)在分布式版本的算法里咱们假如咱们有N个Redis master节点,这些节点都是齐全独立的,咱们不必任何复制或者其余隐含的分布式协调算法。咱们曾经形容了如何在单节点环境下平安地获取和开释锁。因而咱们天经地义地该当用这个办法在每个单节点里来获取和开释锁。在咱们的例子外面咱们把N设成5,这个数字是一个绝对比拟正当的数值,因而咱们须要在不同的计算机或者虚拟机上运行5个master节点来保障他们大多数状况下都不会同时宕机。一个客户端须要做如下操作来获取锁: 获取以后工夫(单位是毫秒)。轮流用雷同的key和随机值在N个节点上申请锁,在这一步里,客户端在每个master上申请锁时,会有一个和总的锁开释工夫相比小的多的超时工夫。比方如果锁主动开释工夫是10秒钟,那每个节点锁申请的超时工夫可能是5-50毫秒的范畴,这个能够避免一个客户端在某个宕掉的master节点上阻塞过长时间,如果一个master节点不可用了,咱们应该尽快尝试下一个master节点。客户端计算第二步中获取锁所花的工夫,只有当客户端在大多数master节点上胜利获取了锁(在这里是3个),而且总共耗费的工夫不超过锁开释工夫,这个锁就认为是获取胜利了。如果锁获取胜利了,那当初锁主动开释工夫就是最后的锁开释工夫减去之前获取锁所耗费的工夫。如果锁获取失败了,不论是因为获取胜利的锁不超过一半(N/2+1)还是因为总耗费工夫超过了锁开释工夫,客户端都会到每个master节点上开释锁,即使是那些他认为没有获取胜利的锁。4.应用示例首先装置redis库与redlock库(官网库,在git上名叫node-redlock),在node我的项目中,间接应用npm或者yarn下载安装即可,redis库我应用的是ioredis(间接装置redis库也可) npm i --save ioredis npm i --save redlock次要用到的办法(官网文档) /** 申请锁 */Redlock.prototype.lock(resource, ttl, ?callback) // resource锁的名称// ttl锁的有效期// callback 回调函数,当应用promise的写法的时候,能够填写这个参数/** 开释锁 */Redlock.prototype.unlock(lock, ?callback)/** 缩短锁的无效工夫 */Lock.prototype.extend(lock, ttl, ?callback)// 都反对callback、promise、yield写法代码示例 const ioredis = require('ioredis') const Redlock = require('redlock') const client = new ioredis(REDIS_SERVER) const redlock = new Redlock([client]) co(function* () { while (true) { let lock = null try { lock = yield redlock.lock('lock', 1000) // 这种写法取不到锁时会间接抛出谬误 } catch (error) { lock = null } yield sleep(30 * 1000) // 解决逻辑 lock.unlock() } })

September 29, 2020 · 1 min · jiezi

关于node.js:Electron-快速入门及最新安装教程

作者:程序员学院官网网址:https://www.chengxuyuan.com微信公众号:华仁程序员学院一、 Electron简介Electron提供了丰盛的本地(操作系统)的API,使你可能应用纯JavaScript来创立桌面应用程序。与其它各种的Node.js运行时不同的是Electron专一于桌面应用程序而不是Web服务器。 Electron 能够让你应用纯 JavaScript 调用丰盛的原生 APIs 来发明桌面利用。你能够把它看作是专一于桌面利用而不是 web 服务器的,io.js 的一个变体。 这不意味着 Electron 是绑定了 GUI 库的 JavaScript。相同,Electron 应用 web 页面作为它的 GUI,所以你能把它看作成一个被 JavaScript 管制的,精简版的 Chromium 浏览器。 二、学习前提因为Electron是一个可能让你应用JavaScript 调用丰盛的原生 APIs 来发明桌面利用,所以你必须把握JavaScript的常识。 三、Electron装置1. 装置 node.jsNode.js官网:https://nodejs.org/zh-cn/,点击下载安装即可,这里不作具体解说。 2. 查看node.js和npm是否装置胜利node -vnpm -v 倡议把npm的仓库切换到国内taobao仓库,注册cnpm命令,如下 npm install -g cnpm --registry=https://registry.npm.taobao.org3、 Electron的装置cnpm install -g electronelectron是否装置胜利可通过命令 electron -v 查看。 4. 打包输入工具cnpm install -g electron-packager 5.electron 客户端工具(electron.exe)关上链接:https://developer.aliyun.com/mirror/NPM?from=tnpm 找到对应版本,我当初装置的版本是:10.1.2 OK,下载下来并解压,能够放到D盘软件装置目录外面,例如:D:\Program Files 好的,咱们当初就装置好了 四、打造咱们的第一个 Electron 利用大体上,一个 Electron 利用的目录构造如下: ...

September 28, 2020 · 2 min · jiezi

关于node.js:node自启动服务nodemon

1.电脑系统 windows10 专业版2.在开发的过程中,依据一些需要,咱们总是会应用到 node进行开发,应用node进行开发的小伙伴们都晓得,当咱们批改node文件的时候,咱们须要从新运行能力看到对应的成果,这样是不是很没有效率,很好受。在这里我的解决办法是:装置一个包nodemon,办法如下。3.在终端执行如下命令: npm install -g nodemon4.装置实现之后,就能够间接应用了: 4-1:例如之前运行命令是:node app.js4-2:当初是:nodemon app.js4-3:如果你运行的是一个脚手架的我的项目,命令是这样:nodemon starting5.本期的教程到了这里就完结啦,是不是很简略,让咱们一起致力走向巅峰,心愿对你有所帮忙,既然咱们抉择了这个畛域,就不要放弃,不要认输,不要抬头,加油。

September 25, 2020 · 1 min · jiezi

关于node.js:node连接mysql

1.开发环境 vue+ node2.电脑系统 windows 10 专业版3.在开的开发的过程中,咱们总是会应用 一门后端语言 来操作数据库,我抉择的是 node,数据库是 mysql ,上面我简略的说一下,应用 node 怎么连贯 mysql 数据库,并把查问到的数据库的数据返回给前端。办法如下:4.在node 中接口中增加如下代码: 4.1 首先 要装置 在 node 中装置 mysql ,代码如下:npm install mysql --save 4.2 在对应的接口中增加如下代码: var express = require('express');var mysql=require("mysql");var router = express.Router();/* GET home page. */router.get('/', function(req, res, next) { res.render('index', { title: 'Express' });});var connection = mysql.createConnection({ host: 'localhost',user: 'root',password: 'chen',database: 'chenuser2',port: '3306'});//创立一个connectionconnection.connect(function(err){ if(err){ console.log('连贯失败:'+err); return; }console.log('连贯胜利');});var chenr=new Array();router.post("/",function(req,res,next){ console.log(req.body); console.log("+++++++++++");connection.query("select * from chenyh",(err,result)=>{ if(err){ console.log("查问失败了"+err); }else{ console.log(result); var data={ code:200, chenmeg:"申请胜利", chenfengdata:{ chenfengname:"你好,我是尘封" } }; res.json([data,result]); }})// var data={// code:200,// chenmeg:"申请胜利",// chenfengdata:{// chenfengname:"你好,我是尘封"// }// };// res.json(data);// res.json(data);}) ...

September 25, 2020 · 1 min · jiezi

关于node.js:关于node的express框架的中间件

论断:其实就是当有申请时,会先解决中间件,等到各种中间件处理完毕,最初才进入路由的办法体。 咱们能够应用use来注册中间件,而后中间件里应用next()来帮忙咱们执行完该中间件后执行下一个中间件,如果没有应用next(),那么申请将会被挂起,并且后边的中间件得不到被执行的机会

September 23, 2020 · 1 min · jiezi

关于node.js:2020年顶级无服务器计算平台

回顾2020年所有次要的无服务器计算服务。 随着云平台的胜利,咱们曾经看到了容许您像应用本人的近程基础设施一样应用近程基础设施的产品(基础设施即服务)。咱们看到的产品容许你应用不同的产品来应用近程基础设施,而不用放心它(平台即服务)。当初,咱们也有能力深刻到代码层面(顺便说一句,这真是太神奇了),只有咱们触发函数,这些函数就会被执行,谁也不晓得在哪里(Functions as a Service)。 在这篇文章中,我将疾速介绍一下有哪些顶级的平台能够让你近程执行自定义计算,或者换句话说。无服务器计算平台。 疾速介绍。什么是无服务器计算?无服务器计算是指可能执行自定义计算,而不用放心计算产生在哪里。当然,服务器是存在的(你认为代码会在哪里运行呢?),但事实上,你不用思考它们,_意味着你能够认为它们是不存在的。 当然,我所说的计算,是指你能够写的理论函数。想想看:在软件开发中,有些时候,你须要创立整个服务,只是为了提供几个性能,同时,这些性能偶然也会被应用,但你依然必须让这个服务在99.9%的工夫里都能失常运行,否则用户可能会须要它们,如果它们失败了,那么你就麻烦了。 如果,你不依附这99.9%的失常运行工夫,而是能保障每当你须要执行该性能时,就启动一个服务器,外面有你须要的所有货色(包含你本人的代码),在执行完结后,所述服务器就会进行?对于一个可能有30%的工夫会被执行,但99.9%的工夫须要启动以备不时之需的服务,这样你能节俭多少钱?这就是无服务器计算平台最大的益处之一,你不必放心基础设施,你只须要放心执行你须要的计算的代码。 乏味的是,这并不是一个新的概念,事实上,里面第一个无服务器服务是在2006年由Zimki推出的,不过它始终没有胜利,最终敞开。从2006年到当初,第一个真正的赢家是亚马逊,他通过Lambda,在2014年胜利推出并遍及了这种服务模式。现在只有它一家吗? 当然不是! 和其余所有基于云的服务一样,各大平台都有,在本文中,我将疾速介绍它们。 为什么要采纳无服务器化?理解什么是无服务器计算很重要,但除此之外,你为什么要应用它?你筹备好失去对服务器及其配置的管制了吗? 事实上,这种模式有不少乏味的益处,我集体认为它们相对超过了你对它的所有潜在保留意见。 无服务器架构是可扩大的 无服务器架构是可扩大的:它们就是这样构建的,你不用放心这个事实。你还想从一个架构中失去什么?你只须要放心编写你的代码,其余的模板代码是不须要的。这相对是一个节省时间的办法,尤其是当初应用的一些技术(也就是node_modules,有人晓得吗?不须要解决服务器配置,因为,嗯......没有服务器(至多,从你的角度来看没有)。这也是一个微小的工夫节俭,不须要装置和配置任何货色,只是假如所有都筹备好了,你能够应用(因为它是)。你只需为你应用的货色付费,所以你不须要为一个总是开着的服务器付费,即便它没有被应用,有了这种模式,你只需为你的代码每次被触发时执行的几秒钟付费。实质上,从实践上讲,所有仿佛都表明,无服务器模式会简化你开发过程中的方方面面以及相干的治理工作。 说到这里,我听到你在问:有什么问题?当然,这种模式也有一个毛病。 为什么你要防止Serverless?在科技行业中,没有什么灵丹妙药;没有一种产品或工作模式能满足你的所有需要,正因为如此,采纳无服务器形式并不总是正确的动作。 例如,无服务器形式有一些毛病。 调试和测试你的代码不是那么简略。你很可能须要一些专门的工具来重现你的代码在无服务器环境下的体现。毕竟,没有服务器就意味着你无法访问失常的环境,在这种环境中你能够调试代码的执行。性能可能是个问题。当初不要误会我的意思,我并不是说无服务器性能很慢,一点也不慢。有一些办法能够让你的代码执行热身,这样如果它常常被应用,就不会受到惩办。但这毕竟是一个无服务器的环境,正因为如此,平时不罕用的函数(或不常常调用的函数)会破费更长的工夫来执行。这取决于提供商和他们采纳的执行计划。无服务器计算并不是为了继续运行而设计的,这意味着你必须从新思考构建逻辑的形式。这是一个扭转你的观点的问题,但这可能是一个挑战,特地是在一开始。厂商锁定相对是实在存在的。我的意思是,这对你来说可能不是一个问题,但如果你想放弃你的代码通用性和厂商无关性,这可能不是方法。你的整个执行过程将是特定于厂商的,所以在决定为模型之前要思考这一点。也就是说,这些与其说是毛病,不如说只是能够被认为是正告。如果你把它们思考进去,你就会没事的。 当初咱们把这些都说分明了,让咱们疾速理解一下次要的无服务器计算提供商。 次要供应商 在思考提供无服务器服务的云提供商时,有很多抉择。所以为了防止写一本小书来介绍所有的抉择,我将列出次要的抉择,如果你还在思考其中没有一个适宜你,至多你会有一个更好的想法来寻找什么。 AWS Lambda相对不是这种模式的发明者,但它依然被认为是第一个真正把所有事件都做对的人,并且让它流行起来。兴许是它背地的商业模式,兴许只是工夫问题,期待技术以可接受的价格提供,但自2014年以来,亚马逊始终在提供Lambda服务,这是在无服务器计算方面最大的名字之一。 他们提供了宽泛的编程语言,你能够应用,而且他们与所有的服务都有集成,容许你依据他们的产品触发的许多事件来触发你的性能的执行。 在他们的网站上,你能够看到如何利用他们的一套服务与lambda函数一起工作,并实现以下性能。 ML模型的数据预处理实时数据分析用于检测趋势*对外服务通信 这相对是一个十分通用的服务,并且领有您可能须要的所有文档和示例。 Azure性能AWS第一个真正的竞争者可能是微软,但2年后,在2016年。他们为FaaS提供的服务与亚马逊的十分类似,当然,集成了他们本人的一套服务和相干的触发器。 如果你要抉择AWS的Lambda的其余服务,这相对是一个完满的抉择。 请记住,这些无服务器计算服务是现实的,当与同一个云提供商的产品联合应用时,成果最好,如果你想让事件跨云工作,那么你可能会开始遇到一些简单的问题(当然,这取决于你到底想实现什么)。 谷歌云性能令人难以置信的是,谷歌捷足先登。他们可能领有世界上最大、最厚道的搜索引擎,但他们为FaaS提供的产品是在2017年,最后,他们的产品比其余替代品慢了不少,这在过后甚至是最差的抉择。 也就是说,一年后,2018年左右,他们设法改善了这方面的状况,他们终于从他们的产品中删除了 "测试版 "标签,并确认当初曾经能够用于生产应用。 现在,他们的服务与竞争对手并驾齐驱,所以尽管他们有一个艰巨的开始,但其相对是一个值得思考的。 咱们该如何抉择? 除了依据你以后的提供商进行抉择(即如果你曾经与AWS单干,你可能会想抉择他们,Azure和GCP也是如此),你须要一些细节来理解哪一个是适宜你的抉择。 所以当初让咱们来看看一些硬性的、无偏见的数据,应该能够帮忙你做出这个抉择。 收费层 理解他们对你的流量不收多少钱和理解他们收多少钱一样重要。 AWS Lambda:100万次执行/月是收费的Azure性能。每月收费执行100万次谷歌云性能。每月收费执行200万次。赢家:很显然,这部分的赢家是谷歌,每个月有2M的收费执行量。也就是说,如果你只是在试水,他们中的任何一家都能提供每月足够的收费执行量供你游玩。 反对的编程语言这些毕竟是函数,你要用什么语言来写,必定是个大问题。而且因为基础设施是治理式的,所以你无奈真正挑选出你最喜爱的那一个,相同,你必须从可用的选项列表中抉择。 AWS Lambda。开箱即用,反对Java,Go,PowerShell,Node.js,C#,Python和Ruby。并可抉择创立自定义运行时,以应用任何你想要的编程语言。Azure 函数。C#、F#、JavaScript、JAVA、PowerShell、Python和TypeScript。具备提供以任何语言编写的HTTP服务作为理论函数的试验性功能。谷歌云函数。JavaScript、Python、Go、JAVA赢家:这里的显著赢家是AWS,Azure紧随其后。为什么呢?因为他们的产品比谷歌的大得多,而且他们都提供了对自定义语言的反对(不像谷歌),但微软的代替计划仍处于预览模式,这意味着它并不真正稳固。 最大执行工夫尽管在编写无服务器性能时,应该思考到这些性能的运行工夫很短,但在一些用例中,可能须要更长的工夫。 AWS Lambda。最高15分钟 *Azure Functions:Azure Functions。通常最多10分钟,但如果你有高级打算,保障最多60分钟。 * 谷歌云函数:Google Cloud Functions:默认为1分钟,但能够保障最长60分钟。默认为1分钟,但能够缩短到9分钟。赢家:如果你要用根本打算的话,这个有点难,AWS Lambda显然是这里的赢家,15分钟。你能设想一个函数运行那么久吗?当然,可能还有一些用例,但这相对是一个很长的工夫。另一方面,如果你违心多付一点钱,Azure的高级打算提供了有限的运行工夫(只管他们只保障最多60分钟,这听起来又很疯狂,应该是足够了)。 理论计算成本最初,为了一个相当大的执行打算,咱们能够冀望每月领取多少钱? 摘自http://serverlesscalc.com/ 通过应用serverlesscalc.com,咱们能够疾速比拟在1.5Gb内存的服务器上执行100万个函数,每个函数均匀运行1秒,须要破费多少钱。 你能够应用这个网站来捉弄这些数字,看看你所看到的差别是什么样的,或者你甚至能够应用每个供应商本人的计算器来对这些预计有更多的管制。 最初,考虑一下即便我应用100万次执行作为例子,他们都有一个收费的层级_至多_这个数量,你依然不得不领取。这是因为即便你没有为申请付费,你依然要为计算工夫付费。如果你应用较低级别的服务器(即在这种状况下内存较少),你的老本会缩小。 ...

September 22, 2020 · 1 min · jiezi

关于node.js:Vue项目报错TypeError-Cannot-read-property-matched-of-undefined

失常状况下应用脚手架跑完之后,而后批改源我的项目,首先在main.js入口里把该import进去的App,vue-router等等都启动好了,接着就是在对应的文件夹和文件外面堆代码了。 import Vue from 'vue'//Vue外围库import ElementUI from 'element-ui' //新增加1import 'element-ui/lib/theme-chalk/index.css'//引入款式import App from './App'//App.vue组件import Router from './router'//路由器import axios from '@/api/http'//Vue我的项目对axios的全局配置import VueAxios from 'vue-axios'路由配置都没什么问题: import Vue from 'vue'import Router from 'vue-router'import Login from '@/components/views/Login.vue'import Regist from '@/components/views/Regist.vue'Vue.use(Router);export default new Router({ routes: [ { path: '/', name: 'Login', component: Login }, { path: '/Regist', name: 'Regist', component: Regist } ]})然而启动后盾报了一个错:有用的只有一句:TypeError: Cannot read property 'matched' of undefined 本次解决形式这个属性,我其实也没见过,然而页面出不来,node也没有报错,就只有浏览器控制台报错的话,个别问题都出在“路由”的下面。原来是我的路由定义出了问题。我将此处的Router改为router:Router,便失常运行了,所以记录以下。如果呈现此类问题,大多数就是路由相干了,排查路由就好了。

September 22, 2020 · 1 min · jiezi

关于node.js:Node-之-Path

Node 之 path1、__dirname 和 __filename 是模块中 的一个内置成员,他们别离是: __dirname 是以后文件夹的绝对路径__filename是以后文件的绝对路径(1)、__diranem:获取到以后文件所在文件夹的绝对路径 例如: 以后文件的地位:vueDemo/src/nodeMain.js (2)、path.join(path1,path2,path3.......) 作用:将门路片段应用特定的分隔符连接起来造成门路,并规范化生成的门路。若任意一个门路片段类型谬误,会报错。 2、path.resolve() path.resolve([from...],to) 作用:把一个门路或门路片段的序列解析为一个绝对路径。相当于"执行cd"操作。 留神: "/" 被解析为根目录。例如:以后文件的地位:vueDemo/src/nodeMain.js 其中: path.resolve(__dirname, "./img/so") 和 path.resolve(__dirname, "img/so") 解析后果一样。

September 22, 2020 · 1 min · jiezi

关于node.js:derrick-创建-nodejs-项目容器

docker 曾经出山很久了,初出江湖就一举成名,在程序员的江湖里声名远扬,作为江湖里的一粒尘埃,早就想从他身上学个一招半式,通过江湖上的口口流传,把握了他的根本套路,用来锤炼锻炼身体很给力。然而始终以来,这一招半式,只能应用构建本人的开发环境,无奈和本人开发的我的项目联合革新为容器化,因为之前没接触过 dockerfile、docker-compose.yml 这些秘籍。偶然间遇到了 derrick 这位高人,分分钟给你写出武林秘籍。 刚开始想用 derrick 创立一个maven我的项目的容器,然而始终报错 [Non-resolvable parent POM and 'parent.relativePath' points at wrong local POM - maven](https://html.developreference.com/article/16790535/Maven%3aNon-resolvable+parent+POM+and+'parent.relativePath'+points+at+wrong+local+POM)原来是因为我的maven我的项目存在父子级依赖,应用过很多办法,仍然报这个问题,果决放弃,就是这么洒脱 前面决定创立一个 nodejs 我的项目容器1.装置 derrick sudo -H pip3 install python-derrickps: 不要遗记 -H; mac 默认是低版本的 Python,我的电脑是 2.7,看下本地有没有3.7版本的python which python以及which pip which python3和which pip3如果没有,则装置 brew install python3。 能够间接 应用 pip3 命令,如果想永恒失效,能够通过在vim ~/.bash_profile 配置别名失效alias python="/usr/local/bin/python3.7"alias python="/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7" alias pip="/Library/Frameworks/Python.framework/Versions/3.7/bin/pip3"2.初始化 derrick derrick configps: 命令不肯定正确哦,跟着提醒来就行了3.生成 dockerfile到我的项目根目录,执行命令 derrick init生成上面的几个文件,Jenkinsfile 是给jenkins应用的,kubernetes-deployment.yaml 是给 kubernetes 应用的,如果只是单纯的docker,只用到 docker-compose.yml、Dockerfile 4.创立镜像到我的项目根目录,执行命令 derrick up执行命令后,会提醒输出镜像名称,输出名称后回车 ...

September 19, 2020 · 1 min · jiezi

关于node.js:for-await-…of-表达式的煎蛋实现小demo

偶然间看到一个小例子: import { serve } from "https://deno.land/std@0.69.0/http/server.ts"; const s = serve({ port: 8000 }); console.log("http://localhost:8000/"); for await (const req of s) { req.respond({ body: "Hello Worldn" }); }查了查资料有了上面这个小demo: const simulateDelay = (val, delay) => new Promise((resolve) => setTimeout(() => resolve(val), delay));class RandomNumberGenerator { [Symbol.asyncIterator]() { return { next: async () => { return simulateDelay({ value: Math.random() }, 200); //return the value after 200ms of delay }, }; }}const rand = new RandomNumberGenerator();(async () => { for await (const random of rand) { console.log(random); if (random < 0.1) break; }})();

September 18, 2020 · 1 min · jiezi

关于node.js:实现微信产品问题反馈群实时监控与问题自动录入上

背景因为咱们的用户都喜爱通过微信群探讨的形式进行产品问题反馈,这无疑给日常的线上问题解决的效率带来极大的影响。已经尝试对用户习惯进行线上填写形式的疏导,但最终以失败告终。无奈下看看弄一个微信群监控机器人是否可行。 在之前公司我已经用python通过itchat弄过一个群播报BI数据的机器人,但因为itcaht采纳的是微信web协定,微信监控特地严,很多号都不能应用,即便登录下来了还会常常莫名掉线,极不稳固。因而这回必定不能再通过web协定的形式来弄了。于是带着一点点期盼发现了Wechaty这个反对微信ipad协定的SDK。 Wechaty官网定义:Wechaty是一个开源的的集体号微信机器人接口,应用Typescript构建的Node.js利用。反对多种微信接入计划,包含网页,ipad,ios,windows,android 等。同时反对 Linux, Windows, Darwin(OSX/Mac) 和 Docker 多个平台。这里必须要重点提一下,Token 是 Wechaty 凋谢源代码我的项目中所设计和反对的一种认证技术,是句子互动公司基于 Wechaty 的 Puppet 实现插件对云服务 API 的受权账号。这也就意味着你在应用Wechaty开发基于ipad协定的机器人之前必须要先拿到可用的token。你能够从Wechaty社区申请到一个15天无效的试用Token,过了试用期后能够抉择付费购买(200RMB/月)或者依照如下介绍尝试获取长期收费的Token:Wechaty Token 申请及应用文档和常见问题 Wechaty目前曾经反对了Java、Python、Go、PHP等多种语言,然而该SDK原生是用TypeScript编写的,并且github上大量的demo和开源我的项目都是用node.js写的,再加上Wechaty声称能够通过6行代码就能够实现一个机器人,于是最终决定用之前一点稚嫩的JavaScript前端开发教训拥抱node.js吧! 参考资料:官网 API文档官网demo:wechaty-getting-startedwechaty-puppet-padplus 示例 。Wechaty社区 开源我的项目通过短时间的学习和尝试后,发现根本微信机器人罕用的性能实现简直都能从这些开源的我的项目中间接拿到,而后再联合本人的需要再进行改装就能够了,的确开发起来挺不便的。 开发之前,首先要明确一下此次的性能需要:主动聊天:群聊中通过 @[机器人]xxx, 机器人回复问题反馈模版信息 (已实现)退出群聊主动欢送:当新的小伙伴退出群聊后主动 @[新的小伙伴] 发一个文字欢送 (已实现)推送机器人登陆二维码到企业微信:机器人掉线后,主动将二维码信息推送给指定企业微信群(已实现)监控群聊信息:实时将聊天记录入库 (已实现)自动识别问题反馈信息:自动识别判断群聊中问题反馈类信息,并收纳入问题库 (开发中)群播报功:每天上班前播报问题收纳和未敞开问题状况 (未开始)我的项目github地址: https://github.com/tomallv/wechat-group-chat-monitoring-robot 一、我的项目构造|-- src/ |---- index.js # 入口文件 |---- config.js # 配置文件 |---- onScan.js # 机器人须要扫描二维码时监听回调 |---- onRoomJoin.js # 进入房间监听回调 |---- onMessage.js # 音讯监听回调 |---- onFriendShip.js # 好友增加监听回调 |---- onDatabaseOperation.js # MySQL数据库操作回调 |---- onEnterpriseWechatBot.js # 企业微信群音讯发送回调 |---- onFileIO.js # 文件读取回调 |-- package.json二、外围包:Wechaty外围包: npm install --save wechatypadplus协定包: npm install --save wechaty-puppet-padplus生成二维码: npm install --save qrcode-terminal三、接下来介绍几个外围代码文件1、配置文件( src/config.js): ...

September 18, 2020 · 4 min · jiezi

关于node.js:给html中的jscss添加版本号解决浏览器缓存

const fs = require("fs");const { join, resolve } = require('path');const execSync = require('child_process').execSync;const { mergeUrl } = require('./url.utils');const findPath = resolve('./dist/template');const rootPath = resolve('./');//文件版本记录const fileVersionNote = {};const toComPath = path => path.replace(//g, '/');//获取版本号const getVersion = (dir, fileName) => { let dirPathPart = toComPath(dir).split('/'); dirPathPart.pop(); let dirPath = dirPathPart.join('/'); fileName = fileName.replace(/^s*(.*?)s*$/, '$1'); if (!/^//.test(fileName)) { fileName = join(dirPath, fileName).replace(rootPath, ''); }else{ fileName = 'dist' + fileName; } return getGitCommitVersion(toComPath(fileName).replace(/^/(.*?)$/, '$1'));}//获取git文件版本号const getGitCommitVersion = (file) => { let gv = null; if(/?/.test(file)){ file = file.replace(/^(.*?)?.*?$/, '$1'); } let noteV = fileVersionNote[file] if (typeof noteV !== 'string' || noteV === '') { if (fs.existsSync(file)) { try { gv = execSync(`git log ${file} | grep commit | awk 'NR==1' | awk -F ' ' '{print $2}'`); gv = gv.toString(); } catch (error) { } } if (typeof gv !== 'string' || gv.length < 10) { console.log('版本号获取谬误', file); noteV = ''; }else{ noteV = gv.substr(0, 7); console.log('新文件git提交号:', file, noteV); } fileVersionNote[file] = noteV; } return noteV;}//读取所有的htmlfunction findHtmlAndAddVersion(dir) { if (fs.existsSync(dir)) { fs.stat(dir, (err, stat) => { if (err || !stat) { return console.error('读取文件状态谬误', err); } else { if (stat.isFile()) { //只是读取html文件 if (/.htm(l){0,1}$/i.test(dir)) { fs.readFile(dir, 'utf8', (err, data) => { if (err) { return console.error('读取文件谬误', err); } else { let html = data.replace(/<link(.*?)hrefs*=s*(['"])(.*?)2(.*?)>/gi, ($0, $1, $2, $3, $4, $5) => { if (/^s*http[s]{0,1}:///i.test($3)) { return $0; } else { return `<link${$1}href="${mergeUrl($3, { _gv: getVersion(dir, $3) })}"${$4}>`; } }).replace(/<script(.*?)srcs*=s*(['"])(.*?)2(.*?)>(.*?)</script>/gi, ($0, $1, $2, $3, $4, $5) => { if (/^s*http[s]{0,1}:///i.test($3)) { return $0; } else { return `<script${$1}src="${mergeUrl($3, { _gv: getVersion(dir, $3) })}"${$4}>${$5}</script>`; } }); fs.writeFileSync(dir, html, function (err) { if (err) { return console.error('文件写入失败', err); } }); } }); } } else if (stat.isDirectory()) { fs.readdir(dir, function (err, files) { if (err || !Array.isArray(files)) { return console.error('读取文件夹谬误', err); } else { files.forEach(file => { findHtmlAndAddVersion(join(dir, file)); }); } }); } else { console.error('文件类型辨认谬误', stat); } } }); } else { console.error('文件夹不存在!!!', dir); }}//增加版本号findHtmlAndAddVersion(findPath);

September 14, 2020 · 2 min · jiezi

关于node.js:Nodejs-中的异步生成器和异步迭代

作者:Alan Storm翻译:疯狂的技术宅 原文:https://alanstorm.com/async-g... 未经容许严禁转载 生成器函数在 JavaScript 中的呈现早于引入 async/await,这意味着在创立异步生成器(始终返回 Promise 且能够 await 的生成器)的同时,还引入了许多须要留神的事项。 明天,咱们将钻研异步生成器及其远亲——异步迭代。 留神:只管这些概念应该实用于所有遵循古代标准的 javascript,但本文中的所有代码都是针对 Node.js 10、12和 14 版开发和测试的。 异步生成器函数看一下这个小程序: // File: main.jsconst createGenerator = function*(){ yield 'a' yield 'b' yield 'c'}const main = () => { const generator = createGenerator() for (const item of generator) { console.log(item) }}main()这段代码定义了一个生成器函数,用该函数创立了一个生成器对象,而后用 for ... of 循环遍历该生成器对象。相当规范的货色——只管你绝不会在理论工作中用生成器来解决如此琐碎的事件。如果你不相熟生成器和 for ... of 循环,请看《Javascript 生成器》 和 《ES6 的循环和可迭代对象的》 这两篇文章。在应用异步生成器之前,你须要对生成器和 for ... of 循环有扎实的理解。 ...

September 14, 2020 · 3 min · jiezi

关于node.js:mysql基础知识-持续更新

mysql 表 查问语句DQL :查问语句排序查问语法:order by 子句排序形式: ASC : 升序,默认的DESC : 降序。留神 : 如果有多个排序条件,则以后边得条件值一样时,才会判断第二条件 SELECT * from userinfo ORDER BY age ASC,id DESC;聚合函数:将一列数据作为一个整体,进行纵向计算count:计算个数 select count(age) from userinfo; -- 返回个数 这种形式是不会把null计算在内得select count(ifnull(age,0)) from userinfo; -- 判断是否是null 是的话 按0来计算select count(8) from userinfo; -- 查问记录 (不举荐) max:计算最大值 select Max(age) from userinfo; -- 计算表中年龄最大得min:计算最小值 select Min(age) from userinfo; -- 计算表中年龄最小的sum:计算和 select sum(age) from userinfo; -- 计算表中所有年龄之和avg:计算平均值 select avg(age) from userinfo; -- 计算表中平均年龄分组查问:语法:group by 分组字段;留神: ...

September 11, 2020 · 2 min · jiezi

关于node.js:AWS-Lambda函数是不可思议的

AWS Lambda函数是不堪设想的! 它们是托管在亚马逊网络服务上的函数,能够以许多不同的形式触发。 其中最好的局部是,您只需为Lambda函数运行的工夫付费。有什么货色一小时才运行一次,而且只须要2秒钟?您每天只需领取48秒的费用! 这与运行一个24/7的AWS EC2实例或你本人的公有服务器相比,几乎太疯狂了。 明天咱们将创立一个Lambda函数,并看看应用代码的三种最佳形式。 创立一个Lambda函数一旦你设置好了AWS账户,有几种办法能够创立一个新的Lambda函数。咱们将应用 AWS Console。 AWS 控制台 在AWS控制台中,你能够在服务下找到AWS Lambda,它能够带你进入Lambda控制台。 如果这是您的第一个Lambda函数,您将看到的就是这个。点击创立一个函数按钮,开始设置您的第一个函数。 您将最终进入设置页面,在这里您能够配置函数的一些方面(名称、运行时、角色)。你能够从Blueprints或Serverless Application Repos中创立一个Lambda,但在这个例子中,咱们将从头开始Author它。 输出你的函数名称(这必须是你的用户或子账户的惟一名称),抉择你的Runtime(咱们将应用Node.js 8.10),并抉择一个角色。 如果你还没有,你必须创立一个新的角色。从模板中创立一个,你能够让政策模板空白。 编写你的Lambda函数代码应用Lambdas的一大劣势是,你能够抉择如何编写和编辑它们。有三种次要形式能够做到这一点 Lambda控制台Cloud9在你的本地机器上我将介绍这三种办法,并探讨它们各自的优缺点。 办法一:Lambda控制台这是你创立函数时被发送到的屏幕。你会看到有很多货色在进行。咱们当初关怀的是函数代码局部,大概在一半处。 在这里咱们有一个根本的编辑器。我置信它是基于Cloud 9 IDE的,对于简略的Lambda函数来说十分好用。你能够看到上面的处理程序是一个异步函数,因为我抉择应用Node 8.10。如果您喜爱回调,那么Node 6.10就是您的运行时。 劣势 这是一个不错的编辑器。你能够通过AWS控制台从任何计算机拜访它。毛病它仿佛不是100%稳固。有时它不容许你保留,所以你必须将你所有的工作复制到本地文件,从新加载页面,而后将你的工作复制回来。我心愿这个问题能尽快失去解决它没有一个终端。这意味着你不能独自应用这种办法应用NPM安装包。办法二:Cloud9编辑器亚马逊最近收买了一个在线开发平台Cloud9。它仿佛运行一个十分根本的Ubuntu版本,与AWS平台的其余局部集成在一起。 在AWS控制台中搜寻Cloud9,进入页面并抉择Create environment_._从这里你给你的环境起个名字,而后进入下一步。 在这里,你能够抉择你想在什么上运行这个环境。最棒的是,t2.micro是收费层的,所以如果你是收费层,你能够应用这个办法而不被收取任何费用。我素来没有须要比t2.micro更弱小的货色。 从这里持续往前走,你将最终进入你的新Cloud9环境! 最酷的是,您能够从Cloud9环境外部拜访您的所有Lambda函数。点击AWS资源,在近程函数下,您会发现您所有的函数。点击您要编辑的Lambda函数,而后点击下面的下载图标,将其导入到您的环境中。 实现后,就像你在本地工作一样。 一旦你实现了,只需从本地列表中抉择你始终在做的性能,而后点击上传按钮。在几秒钟内,它就会带着你所有的批改上线。 劣势 同样,这是所有的近程,所以你不须要放心遗记提交你的工作,或保留到记忆棒,如果你在多台机器上工作。获取你的函数并上传它们是超级简略的。这是目前这种办法最棒的一点。你当初有了一个集成的终端,容许你装置npm包,并应用终端做其余所有你想做的事件。毛病它依然存在Lambda编辑器一样的稳定性问题。我曾多次想保留函数,但无奈保留,只能复制到本地,刷新,再从新复制到云9。几次之后,我放弃了,转到本地编辑。办法3:本地编辑这个我就不一样了,我会把优缺点列出来,而后通知你如何让它变得更好。 劣势 本地编辑是大多数开发者的工作形式。咱们能够应用咱们最喜爱的IDE,扩大和色彩计划。它是稳固的(只有你的电脑是稳固的)。毛病没有花哨的按钮来获取和上传你的作品到AWS。你的作品是本地的,所以有多个用户或只是在多个设施上工作是比较复杂的。本地编辑技巧因为这种办法的长处是如此吸引人(或者说其余办法的毛病是如此骇人听闻),咱们将利用一些根本的变通方法。设置咱们须要的所有货色应该须要15分钟左右! AWS CLI要将咱们的工作上传到AWS,咱们能够应用AWS CLI。这容许咱们将一个压缩文件上传到咱们的AWS帐户,填充给定的Lambda。 要做到这一点,咱们首先须要设置AWS CLI。你能够应用本教程或在终端中输出npm install -g aws-cli来装置它。当初,咱们须要为咱们的CLI设置一个用户,以便作为用户登录。 ...

September 10, 2020 · 1 min · jiezi

关于node.js:node练习

1、node实现登录 /** * 登录零碎 * @param {String} username 用户名 * @param {String} password 明码 */async function login(username, password) { const res = await fetch(`${BASE_URL}/websys/xxx/login.do`, { credentials: 'include', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Referer': ' http://xxx.com.cn/websys/xxx/index.html' }, body: qs.stringify({ name: username, pwd: password }) }) const matchArr = res.headers.get('set-cookie').match(new RegExp('sys_auth?=([^;]+)')); const sys_auth = matchArr && matchArr[1]; if (!sys_auth) { throw new Error('登录谬误,请确认用户名或明码是否正确'); } cookie = `SITE=alm01; ws_auth=${ws_auth};` // 全局保留登录token}/** * 根据登录token申请后续接口 */async function getPlans(planId) { return await fetch(`${BASE_URL}/websys/xxx/${planId}/plan/?planList`, { credentials: 'include', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Cookie': cookie }, body: qs.stringify({ pageSize: 10, pageNo: 5, }) }) .then(res => res.json()) .then(data => data.plans.rows);}2、node操作excel ...

September 9, 2020 · 1 min · jiezi

关于node.js:Kiss-Iconfont

装置 iconfontcnnpm install -g iconfontcniconfontcn 有什么用简化 iconfont 的应用提供了更灵便的 Icon 组件iconfont 是什么?阿里妈妈 MUX 倾力打造的矢量图标治理、交流平台,设计师将图标上传到 iconfont 平台,用户能够自定义下载多种格局的 icon,平台也可将图标转换为字体,便于前端工程师自在调整与调用。 iconfont 的 Web 端应用形式https://www.iconfont.cn/help/...unicode 援用font-class 援用symbol 援用,全新的应用形式,将来的支流通过 iconfontcn 应用 iconfont查看 iconfont 我的项目的 Font Family、FontClass/Symbol 前缀信息 iconfont.cn > 资源管理 > 我的我的项目 > 更多操作 > 编辑我的项目查看 iconfont 我的项目的 Font class/Symbol iconfont.cn > 资源管理 > 我的我的项目 > Font class / Symbol我的项目 index.js 中初始化 iconfontcn(只须要初始化一次) import Iconfont from "iconfontcn";// init参数阐明//Iconfont.init("Font class/Symbol地址", "FontClass/Symbol 前缀", "Font Family");// font-class援用Iconfont.init("font_2043983_voy5aew0vz.css", "t-", "testfont");// symbol援用Iconfont.init("font_2043983_voy5aew0vz.js", "t-");Icon 组件属性和应用 ...

September 9, 2020 · 1 min · jiezi

关于node.js:withoutcdn

Web 我的项目应用 CDN 资源能减速我的项目的拜访,然而有时候我的项目部署在内网或者咱们选用的 CDN 不稳固,就会呈现我的项目部署后无奈失常运行的难堪状况。 把 CDN 资源全副放在本地,我的项目中就会多出一些额定的目录和文件(这些文件万年不须要批改,一不小心点开还可能被编辑器格式化了),而且还须要提交进代码库,当须要对援用 CDN 资源降级或者更换版本时,又须要反复去下载对应的资源提交到我的项目中,还须要移除之前的版本文件。 如果你开发的过程中也碰到过下面的小难堪,倡议你试试 without-cdn,说不定能带给你一点小惊喜。 装置 without-cdn倡议全局装置,能够间接在命令行中应用$npm install -g without-cdn劣势&工作原理劣势: 开发过程中能够应用 CDN 资源,CDN 资源不必下载到本地,批改 url 即可更换资源版本,且仅在我的项目部署时下载和替换 CDN 资源 工作原理: 对须要解决的文件中 script 和 link 标签进行提取,剖析出以 http 结尾的 url将提取的 http url 列表下载到指定的本地目录更换文件中的 http url命令行应用$ withoutcdn --helpOptions: -V, --version output the version number -f --filepath <string> the file path that to be processed -e --exclude <string> exclude the CDN path, multiple paths use commas to separate -d --folder <string> destination folder for the CDN file -lo --logsoff logs off -h, --help display help for commandOptions: -V, --version 显示版本 -f --filepath <string> 必填参数,须要解决的文件门路,留神门路是否无效(应用\\或/),反对全门路、相对路径 -e --exclude <string> 疏忽的门路,反对配置多个门路,用半角逗号宰割。例如我的项目中应用了多个CDN,自建的CDN门路不须要下载替换,能够配置exclude。 -d --folder <string> CDN文件下载的目录名称,如不存在会在解决文件的同一门路下创立 -lo --logsoff 是否打印日志,加上-lo或--logsoff敞开日志输入 -h, --help 显示帮忙// build后的index.html,应用了bootcdn的jquery和alicdn的font文件<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link rel="shortcut icon" href="/favicon.ico"/><title>XXXX有限公司</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/2.1.2/jquery.min.js"></script><script src="http://at.alicdn.com/t/font_2031940_kylw1ml1bn.js"></script>.....// 应用withoutcdn解决index.html$ withoutcdn -f ./index.html -d staticwithoutCDN start...find CDN fileList:https://cdn.bootcdn.net/ajax/libs/jquery/2.1.2/jquery.min.jshttp://at.alicdn.com/t/font_2031940_kylw1ml1bn.jsdownload http://at.alicdn.com/t/font_2031940_kylw1ml1bn.js successfully.download https://cdn.bootcdn.net/ajax/libs/jquery/2.1.2/jquery.min.js successfully.// 解决后的index.html,同时./static目录下多出了font_2031940_kylw1ml1bn.js jquery.min.js<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link rel="shortcut icon" href="/favicon.ico"/><title>XXXX有限公司</title><script src="./static/jquery.min.js"></script><script src="./static/font_2031940_kylw1ml1bn.js"></script><style>...JS 中应用```const withoutCDN = require("without-cdn");// 参数阐明withoutCDN({ log: boolean, // 是否打印日志 filepath: string, // 必填参数,须要解决的文件门路,留神门路是否无效(应用\\或/),反对全门路、相对路径 exclude: string | string[], // 疏忽的门路,反对应用数组配置多个门路 folder: string // CDN文件下载的目录名称,如不存在会在解决的文件同一门路下创立});withoutCDN({ filepath: "build/index.html", folder: "static"});```React 我的项目打包时应用 without-cdn办法一:全局装置 without-cdn,在 package.json 的 scripts 中应用 post 钩子,举荐应用该办法 ...

September 9, 2020 · 2 min · jiezi

关于node.js:nodejs数据库orm扩展sequelize

sequelize是nodejs版的orm库,用过laravelORM的能很快能上手具体文档官网github简略代码democonst { Sequelize, DataTypes, Model, QueryTypes, Op } = require("sequelize");const sequelize = new Sequelize("sqlite://sql.db", { logging: false });class User extends Model {}class Address extends Model {}User.init( { // 在这里定义模型属性 id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, }, name: { type: DataTypes.STRING, unique: true, // allowNull 默认为 true validate: { async isUnique(name) { const res = await User.findOne({where: {name}}) if (res) throw new Error('用户名已存在') }, // len: [1,2] } }, }, { // 这是其余模型参数 sequelize, // 咱们须要传递连贯实例 // modelName: "User", // 咱们须要抉择模型名称 tableName:'users' // 表名,默认为模型名的复数单词 });Address.init( { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, }, name: { type: DataTypes.STRING, unique: true, // allowNull 默认为 true }, }, { sequelize, modelName: "Address", });// 模型关系 多对多User.belongsToMany(Address, { through: "userAddress", as:'addres' }); // through 代表两头表的名字,as是查问别名Address.belongsToMany(User, { through: "userAddress" });(async () => { try { // await sequelize.sync({ alter: true }); // 同步模型到数据库-创立表 // const user = await User.findOne({ where: { name: {[Op.like]:'%小%'} } }); // 根本查问 const [user] = await User.findOrCreate({where:{name:'小小'},include:'addres'}); // 顺带查问到关联模型的数据 const [address] = await Address.findOrCreate({where:{name:'小小de地址'}}); await user.addAddress(address); // 关联减少 console.log(user.toJSON()); } catch (e) { console.log(e); }})();

September 4, 2020 · 1 min · jiezi

关于node.js:windows下安装nodejs

一、什么是nodejs Node.js 是一个基于 Chrome V8 引擎的javascript运行环境。 Node.js 应用了一个事件驱动、非阻塞式 I/O 的模型。 Node 是一个让 JavaScript 运行在服务端的开发平台,它让javascript成为与PHP、Python等服务端语言分庭抗礼的脚步语言。 由大神大神 Ryan Dahl 于2009年开发的。 实质上node.js不是库,是一个运行环境或者是一个js语言解释器 二、windows下装置2.1 下载安装包官网进行nodejs下载,如下图所示,依据windows的版本抉择32或64位的安装包下载。 2.2 双击安装包装置能够间接一路next上来, 进行装置地位的抉择,我个别装在D盘中 ...,最终点击finish 2.3 检测nodejs装置当执行完上步安装包装置后,须要进行装置是否胜利,win+r关上运行,输出cmd后进入命令行界面。别离输出node -v和npm -v命令进行node的版本号和npm的版本号的查看。 装置完后的目录如下图所示 目录中的npm随安装程序主动装置,作用:对Node.js依赖的包进行治理2.4 配置npm装置全局模块的门路与缓存门路个别,在进行npm install ...等命令全局装置时,默认的会将模块装置C:\Users\用户名\AppData\Roaming门路下的npm和npm_cache中。 此时可不进行批改,但便于对C盘数据进行治理,此时这里配置咱们自定义的全局模块装置门路和缓存门路,在以后的nodejs装置目录下新建两个文件夹,别离为node_global和node_cache`。 此时须要win+r关上运行,输出cmd进入命令行界面,别离输出以下内容执行 npm config set perfix "D:\Program Files\nodejs\node_global"npm config set cache "D:\Program Files\nodejs\node_cache"2.5 进行环境变量的配置在零碎变量中新建NODE_PATHNODE_PATH D:\Program Files\nodejs\node_global\node_modules在用户变量中编辑用户变量的path,批改对应的npm的门路值为上文中自定义的node_global门路D:\Program Files\nodejs\node_global2.6 执行测试win+r关上运行cmd,执行npm install webpack -g 装置webpack,呈现下图即配置实现。 在自定义的文件中也会相应的显示如下内容

September 2, 2020 · 1 min · jiezi

关于node.js:nodejs的mysql库promise化

promise化const mysql = require("mysql");const pool = mysql.createPool({ host: "127.0.0.1", user: "root", password: "", port: "3306", database: "test",});const sqlQuery = (sql, values) => { return new Promise((resolve, reject) => { pool.getConnection((err, connection) => { if (err) { reject(err); } else { if (values) { connection.query(sql, values, (err, rows) => { if (err) { reject(err); } else { resolve(rows); } connection.release(); }); } else { connection.query(sql, (err, rows) => { if (err) { reject(err); } else { resolve(rows); } connection.release(); }); } } }); });};应用(async ()=>{ const data = await sqlQuery(`select * from user limit 10`); console.log(data)})()

September 2, 2020 · 1 min · jiezi

关于node.js:在nodejs服务器和ABAP服务器上使用jsonp

In my blog Cross domain request in ABAP and Java with two workaround I introduce the step how to deal with Cross Domain issue using Cross-origin resource sharing ( CORS ) supported by almost all modern browsers. And there is another alternative for cross domain issue, that is JSONP which can work on legacy browsers which predate CORS support. In this blog, I will first explain how to use JSONP and then introduce the secret behind it. ...

August 30, 2020 · 4 min · jiezi

关于node.js:PM2-源码分析

近期有需要须要理解 PM2 一些性能的实现形式,所以趁势看了一下 PM2 的源码,也算是用了这么多年的 PM2,第一次进入外部进行一些摸索。 PM2 是一个 基于 node.js 的过程管理工具,自身 node.js 是一个单过程的语言,然而 PM2 能够实现多过程的运行及治理(当然还是基于 node 的 API),还提供程序零碎信息的展现,包含 内存、CPU 等数据。PM2 的外围性能概览源码地位 官方网站PM2 的性能、插件十分的丰盛,但比拟外围的性能其实不多: 多过程治理零碎信息监控日志治理其余的一些性能就都是基于 PM2 之上的辅助性能了。 我的项目构造PM2 的我的项目构造算是比拟简洁的了,次要的源码都在 lib 目录下, God 目录为外围性能多过程治理的实现,以及 API 目录则是提供了各种能力,包含 日志治理、面板查看零碎信息以及各种辅助性能,最初就是 Sysinfo 目录下对于如何采集零碎信息的实现了。 # 删除了多个不相干的文件、文件夹lib├── API # 日志治理、GUI 等辅助性能├── God # 多过程治理逻辑实现地位└── Sysinfo # 零碎信息采集几个比拟要害的文件作用: Daemon.js 守护过程的次要逻辑实现,包含 rpc server,以及各种守护过程的能力God.js 业务过程的包裹层,负责与守护过程建设连贯,以及注入一些操作,咱们编写的代码最终是由这里执行的Client.js 执行 PM2 命令的次要逻辑实现,包含与守护过程建设 rpc 连贯,以及各种申请守护过程的操作API.js 各种功能性的实现,包含启动、敞开我的项目、展现列表、展现零碎信息等操作,会调用 Client 的各种函数binaries/CLI.js 执行 pm2 命令时候触发的入口文件守护过程与 Client 过程通信形式看源码后会晓得,PM2 与 Client 过程(也就是咱们 pm2 start XXX 时对应的过程),是通过 RPC 进行通信的,这样就能保障所有的 Client 过程能够与守护过程进行通信,上报一些信息,以及从守护过程层面执行一些操作。 ...

August 29, 2020 · 2 min · jiezi

关于node.js:Node-在-Controller-层如何进行数据校验

本文收录于 GitHub 山月行博客: shfshanyue/blog,内含我在理论工作中碰到的问题、对于业务的思考及在全栈方向上的学习 前端工程化系列Node进阶系列风趣有趣的后端程序员个别自嘲为 CURD Boy。CURD, 也就是对某一存储资源的增删改查,这齐全是面向数据编程啊。 真好呀,面向数据编程,往往会对业务了解地更加透彻,从而写出更高质量的代码,造出更少的 BUG。既然是面向数据编程那更须要防止脏数据的呈现,增强数据校验。否则,难道要置信前端的数据校验吗,毕竟前端数据校验中转用户,是为了 UI 层更敌对的用户反馈。 数据校验层后端因为重业务逻辑以及待处理各种数据,以致于分成各种各样的层级,以我经验过的后端我的项目就有分为 Controller、Service、Model、Helper、Entity 等各种命名的层,形形色色。但这里必定有一个层称为 Controller,站在后端最上层间接接管客户端传输数据。 因为 Controller 层是服务器端中与客户端数据交互的最顶层,秉承着 Fail Fast 的准则,肩负着数据过滤器的性能,对于不非法数据间接打回去,如同秦琼与尉迟恭门神般森严。 数据校验同时衍生了一个半文档化的副产品,你只须要看一眼数据校验层,便晓得要传哪些字段,都是些什么格局。 以下都是常见的数据校验,本文讲述如何对它们进行校验: required/optional根本的数据校验,如 number、string、timestamp 及值须要满足的条件简单的数据校验,如 IP、手机号、邮箱与域名const body = { id, name, mobilePhone, email}山月接触过一个没有数据校验层的后端我的项目,if/else 充斥在各种层级,万分苦楚,分分钟向重构。 JSON SchemaJSON Schema 基于 JSON 进行数据校验格局,并附有一份标准 json-schema.org,目前 (2020-08) 最新版本是 7.0。各种服务器编程语言都对标准进行了实现,如 go、java、php 等,当然平凡的 javascript 也有,如不温不火的 ajv。 以下是校验用户信息的一个 Schema,可见语法简单与繁琐: { "$schema": "http://json-schema.org/draft-04/schema#", "title": "User", "description": "用户信息", "type": "object", "properties": { "id": { "description": "用户 ID", "type": "integer" }, "name": { "description": "用户姓名", "type": "string" }, "email": { "description": "用户邮箱", "type": "string", "format": "email", "maxLength": 20 }, "mobilePhone": { "description": "用户手机号", "type": "string", "pattern": "^(?:(?:\+|00)86)?1[3-9]\d{9}$", "maxLength": 15 } }, "required": ["id", "name"]}对于简单的数据类型校验,JSON Schema 内置了以下 Format,方便快捷校验 ...

August 28, 2020 · 2 min · jiezi

关于node.js:译使用频率最高的前30个Nodejs面试问题-の-1120

作者 • Dhanjiv Pandey • 本文出处 • 已取得中译受权• 作者twitter• 译者主页 译者按: 2018年的文章,其中局部问题放在明天依然不算过期。# Q-11:什么是回调天堂?一开始,你能够在理解回调后褒扬它。回调天堂是大量嵌套的回调,这使得代码难以浏览和保护。 让咱们看看上面的代码示例: downloadPhoto('http://coolcats.com/cat.gif', displayPhoto)function displayPhoto (error, photo) { if (error) console.error('Download error!', error) else console.log('Download finished', photo)}console.log('Download started')在这种状况下,Node.js首先申明 displayPhoto 函数。尔后,它将调用 downloadPhoto 函数并传递 displayPhoto 函数作为其回调。最初,该代码在管制台上显示Download started 。仅在 downloadPhoto 实现其所有工作的执行后,才会执行 displayPhoto 。 # Q-12:如何防止在Node.js呈现回调天堂?Node.js在外部应用单线程事件循环来解决排队的事件。然而,如果工作的运行工夫比预期的长,则此办法可能导致阻塞整个过程。 Node.js通过合并回调(也称为higher-order函数)解决了此问题。因而,只有长时间运行的过程实现执行,就会触发关联的回调。通过这种办法,它能够容许代码在长时间运行的工作之后继续执行。 然而,上述解决方案看起来十分有前途。然而有时候,这可能会导致简单且无奈读取的代码。更多的状况下它会导致返回的回调链将更长。 因为这种前所未有的复杂性,调试代码十分艰难,可能会消耗大量工夫。有四种解决方案能够解决回调天堂问题。 1. 程序模块化. 它倡议将逻辑分为较小的模块。而后从主模块将它们连贯在一起以达到所需的后果。 2. 应用 async 机制. 它是一个宽泛应用的Node.js模块,提供了一个间断的执行流。异步模块具备 async.waterfall API,该API应用下一个回调将数据从一个操作传递到另一操作。 另一个异步API async.map 容许并行遍历我的项目列表,并应用另一个后果列表进行回调。 应用异步办法,调用者的回调仅被调用一次。这里的调用者是应用async模块的主办法。 3. 应用 promises 机制. Promises 提供了另一种编写异步代码的办法. 它们要么返回执行后果,要么返回 error/exception.实现promise须要应用 then() 函数,该函数期待 promise 对象返回。它带有两个可选参数,是两个函数。依据promise的状态,只有一个会被调用。如果promise失去实现,则将执行第一个函数调用。然而,如果Promise被回绝,则将调用第二个函数。 ...

August 26, 2020 · 2 min · jiezi

关于node.js:nodemodules打补丁

装置patch-packagepatch-package包能够通过npm进行装置。 npm i patch-package --save-dev或者也能够通过yarn进行装置。 yarn add --dev patch-package postinstall-postinstall创立补丁在批改依赖包内容后,就能够运行patch-package创立patch文件了。 $ npx patch-package package-name # 应用npm$ yarn patch-package package-name # 应用yarn运行后通常会在我的项目根目录下的patches目录中创立一个名为package-name+version.patch的文件。将该patch文件提交至版本控制中,即可在之后利用该补丁了。 部署实现上述操作后,最初还须要批改package.json的内容,在scripts中退出"postinstall": "patch-package"。 "scripts": { "postinstall": "patch-package"}至此,在后续运行npm install或是yarn install命令时,便会主动为依赖包打上咱们编写的补丁了。

August 26, 2020 · 1 min · jiezi

关于node.js:记录下安装新版sharp的折腾史

前两天顺手降级了一下sharp的依赖到最新版(0.25.4),后果捅了马蜂窝,cnpm, npm均告失败,折腾了良久才解决,好郁闷,这里顺便记录一下。 cnpm遇到的问题就是新版sharp的装置脚本会主动去github的releases外面下载预编译好的libvips二进制包,这个货色并不能通过cnpm的淘宝仓库减速,然而因为家喻户晓的起因,国内下载github的releases那不是慢的问题,是间接卡死…… npm遇到的问题第二步,尝试一下npm加代理吧,本人有个始终用的小机场的,因而首先须要在Linux上装置一个python版某乳客户端,不过py版外面不像C#版自带privoxy,因而只能间接作为socks5代理应用,设置为npm代理: npm config set proxy "socks5://localhost:1080"npm config set https-proxy "socks5://localhost:1080"尝试npm install sharp来装置,后果还是不行!看了下错误信息: info sharp Downloading https://github.com/lovell/sharp-libvips/releases/download/v8.9.1/libvips-8.9.1-linux-x64.tar.gzERR! sharp tunneling socket could not be established, cause=Parse Error: Expected HTTP/竟然不能用socks5代理,还必须得用HTTP!好烦! 装置PrivoxyC#版的某乳客户端就是用privoxy来把socks5代理转换为http代理的,因而在linux上如法炮制: # 装置privoxy,centos下用yumapt-get install privoxy# 批改privoxy配置文件,在开端增加一行(留神最初的.):# forward-socks5 / 127.0.0.1:1080 .vi /etc/privoxy/config# privoxy作为服务启动service privoxy start# 验证一下HTTP代理是否失常curl -x localhost:8118 https://www.baidu.com# 把npm的代理设置为httpnpm config set proxy "http://localhost:8118"npm config set https-proxy "http://localhost:8118"从新运行npm install sharp,终于失常了!

August 24, 2020 · 1 min · jiezi

关于node.js:B2B-是否要做AB-Test

AB Testing在软体工程畛域是一个耳熟能详的词,大家都晓得AB Test的重要性。当产品经理提出的需要不合里(太难做)时,程序员们心理总是os,你怎么晓得客户到底要什么,不也是拍脑袋想的吗,这时候咱们可能会提出另一种作法,并要求他(她)去做一个AB Test来验证哪一个作法更好。 然而,大家可能不晓得,要做一个胜利的AB Test试验,它背地的老本是十分微小的。首先,你必须做许多的剖析,理解用户习惯与需要,而后做出正当的假如并决定变数(variation),接著,须要工程部门帮助将AB Test进行实作并采集相干数据,有了数据之后,产品经理须要依据假如建设模型来验证假如,一直迭代最初取得一个论断。这个老本在B2B中尤其宏大,影响因素十分的多,蕴含取样率、用户个性等,这也使得许多B2B畛域的产品经理对AB Test望而怯步。 那么,到底在B2B畛域中要不要做AB Test呢?本篇大哉问就要带大家来探讨下这个问题了! 什么是AB Test在开始大哉问之前,想先跟大家科普一下何谓AB Test,也让咱们在后续探讨时能有更多的共鸣。 AB Test是一种以统计为导向的测试方法,在一个页面中,针对某一场景进行两种或以上的假如,并在同一时间内对不同的用户进行测试,以察看用户的反馈。 AB Test通常蕴含以下的流程: 首先,在进行AB测试之前,产品经理须要先针对场景进行钻研,并建设假说。接著,从假说当中演绎出变数,来决定试验如何进行,有了这些前置步骤后,就能进入到真正的测试环节,将两种假说实现到产品当中并投放给不同的人群进行应用以蒐集数据。最初,产品经理须要针对这些反馈数据进行剖析,以取得试验后果并确立计划。 咱们用几个实在的案例来形容一个AB Test是如何进行的。 实在案例:form表单设计 第一个案例是某云计算产品相干公司的报价单产生零碎。产品经理在设计阶段调研了自家产品目前用户的报价习惯与流量,演绎出了A与B两种报价单的设计假说。其中A版本是一份具体的报价单,外面波及了具体的配置与规格,设计上给人一种业余感,没有过多的装点。B版本是一份看起来比拟平易近人的报价单,须要填写的材料绝对较少。这两种设计别离示意了两种假如,第一种假如是一份具体的报价单能凸显业余度,使用户置信业余并违心来填写报价单,另一个则假如简略的填写表格能让用户更有志愿来填写。在变数上,蕴含了填写的难易水平、好看性、提交按钮的显易水平等等。 通过假说与变量管制后,最初落地的就是上图两个版本的表单,产品经理别离在同一时间对不同用户投放并蒐集数据。通过继续察看语剖析,最初B表单胜出,流量差距高达385%。证实了平易近人的表单设计更受用户青睐。 实在案例:DHL折扣广告 第二个案例是国内出名快递公司DHL的折扣广告。产品经理在设计广告时设立了两个假说,女性的广告代言人更加吸引民众的眼光,以及,男性的广告代言人更加吸引民众的眼光。因而,这里的变量就很显著,角色的性别对流量的影响。通过投放测试后发现,女性的广告代言人更加的吸引人,转化率比男性代言人高了8个百分比,阐明对民众来说,女性代言人更具亲和力且更违心点击购买,是不是很乏味? 能够把B2C畛域的教训间接套用到B2B畛域吗?答案是不行的,两个畛域个性相差太大。如同后面所说的,一个胜利的AB Test大略会经验几个阶段。蕴含钻研、建设假说、建设与执行试验、评估后果并验证假说等。 在试验过程中,试验后果通常有两种可能,第一是试验后果具备强有力的统计论证以证实假说的正确性,二是试验后果不具备足以证实假说的证据(在AB Test中这很常产生)。如果你的试验具备强有力的证据撑持每一个假说并且试验的过程是很快的,那么这样的AB Test将会十分有效率。在B2C场景中,假说绝对容易造成,因为数据量大,所蒐集的数据具备统计意义,更不便产品经理造成假说,也因而做AB Test相对来说更有效率。然而,在B2B畛域中就不是这么一回事了。因为B2B的客户面相的是公司,在取样率上远远比不上C端用户,这也导致B2B畛域的统计个性单薄,假说也绝对难以造成。 另一个不行的起因在于流量。在B2C畛域中,流量与收益经常是成正比关系,越多的流量就能带来越多的收益,因而在进行变量管制时,流量总是会随机地调配到一个或数个变量当中。然而,在B2B畛域中,流量不全然反比于收益,拜访B2B网站的用户中,可能很大一部分是游客,他们可能是透过广告或搜寻进到网页当中进行调研。他们并不会花钱,因为他们可能只是企业员工的一员,没有决定洽购的势力。这使得许多在B2C畛域中曾经耳熟能详的决策模型变得毫无用武之地。 AB Test在B2B畛域中的挑战B2B畛域的产品经理们当初面临了三个AB Test的挑战: 难以制订最佳的KPI指标须要大量的资源来进行AB Test须要很长的工夫能力失去后果1. 难以制订最佳的KPI指标在B2B场景中,咱们所关注并且心愿达到的后果往往是支出。现实上,咱们在做试验时,应以支出为次要考量因子。在理论场景中,许多的B2B产品经理会将指标细化成应用潜在客户的转化率(如中长尾客户)、渠道机会(如客户单干等)与市场影响支出(如产品市场占有额)等评估指标,在SaaS中,可能会以LTV(生命周期总价值)作为次要的掂量指标。 如果你没方法测量这些指标,那就意味著你没方法最佳化它。当初市面上大多数的AB Test工具都是针B2C场景,这意味著你没方法间接套用这些工具,因为他们所应用的量测指标没方法满足B2B的场景。 2. 须要大量的资源来进行AB Test假如咱们要做一场最节省成本的AB Test试验,那咱们至多须要UED相干的设计师、前端开发工程师与数据分析工程师投入到这场试验当中。投入的工夫也不是短暂的(一两个礼拜),因为一场胜利的试验,必须长时间的察看以获取无效的样本数及防止落入「錯誤测试」当中。在B2C畛域中,测试的工夫绝对较短,因为样本数能够很容易地被满足,同时取样自身根本合乎常态散布。但在B2B畛域中测试的工夫绝对会被拉长,除了样本数的起因外,另一个重要因素是取样偏差,因为在B2B畛域中可能大多数的流量皆是访客,只有少部分人能成为真正带来收益的用户。因而,同样的人力资源在B2B的实验场中须要停留的工夫就更久,须要剖析的数据也更加简单且可能无意义。 3. 须要很长的工夫能力失去后果如同2中所述,在B2B畛域中因为样本数有余与样本偏差问题,会导致整体试验工夫被拉长。然而,消耗的工夫可能还不止于此。一般来说,AB Test是一个周期性并且迭代的一个过程,因为咱们须要依据试验的后果来修改假说或从新定义变数,这会使得原本破费工夫就长的试验变本加厉。也因而要取得后果的工夫会比B2C畛域长的更多。 那B2B畛域还须要做AB Test吗? 看了下面那么多的挑战,咱们还须要在B2B畛域中做AB Test吗?我的答案是必定的。因为AB Test所能带来的收益也是微小的。我认为的长处: 1. AB Test能够帮忙B2B产品更好的取得业务反馈 B2B产品尽管在用户体系上与B2C产品截然不同(客户不肯定是用户),然而,咱们仍然能够透过服务好用户来影响客户的形式,来间接的减少收益。因而,怎么从AB Test当中获取用户的反馈来改良产品是很重要的。2. AB Test能够帮忙B2B产品减少流量 流量尽管在B2B产品中不是次要的掂量指标(因为与收益不肯定成正比),然而,它的边际效益却能间接的达成收益的目标。例如下面所提到的市场影响支出、渠道机会等等。因而,透过AB Test,咱们能够更好地改善产品来晋升流量以达成收益的目标。3. AB Test能够帮忙B2B产品更好的摸索市场 ...

August 24, 2020 · 1 min · jiezi

关于node.js:爱奇艺中国新说唱2020弹幕分析制作不完全数据大屏

爱奇艺《中国新说唱2020》弹幕剖析,制作不齐全数据大屏《中国新说唱2020》不齐全数据大屏哇咔咔,爱奇艺《中国新说唱2020》如期而至,作为掉以轻心的伪嘻哈迷,以及与世无争的梅格妮,那相对是必追无疑(单压X4 cool~)。在看视频的同时我还制作了一个爱奇艺《中国新说唱2020》不齐全数据大屏,感兴趣的敌人能够点这里 https://www.fishhere.fun/rap 先睹为快。 获取爱奇艺弹幕想要制作大屏,第一步就是要获取数据。咱们先来看下弹幕。其实这一步骤还是很简略的,网上有很多的先驱者,网友们也写的很分明,轻易搜寻一下就能够晓得怎么获取了,不过大多人都是用 python,我这里用的是 node。 关上网页控制台,搜寻“bullet”,点 z 结尾的就是咱们要找的链接。 链接中的最初一个数字每隔300秒加1,直到视频完结。所以遍历的次数为视频时长除以300且向上取整。视频分高低两集,所以还要再执行两次。 应用 node 申请数据,这里应用了 eggjs 框架。const res = await this.ctx.curl(url, { // gzip: true,});是否反对 gzip 响应格局,默认为 false。 开启 gzip 之后,HttpClient 将主动设置 Accept-Encoding: gzip 申请头, 并且会主动解压带 Content-Encoding: gzip 响应头的数据。(摘自 eggjs 官网文档)这里获取到的是一个 buffer 格局的文件,我认为将 gzip 设置为 true,就能够拿到解压后的文件,但其实不然。 应用 node 的 zlib 解压文件,最初就能够拿到正确的文件。 制作词云用 xml2js 操作 xml 文件const xml2js = require('xml2js');const parser = new xml2js.Parser();parser.parseString(xmlData, function (err, result) { console.log(result)})用 nodejieba 抽取关键词const nodejieba = require("nodejieba");let result = nodejieba.extract(sentence, 100);console.log(result) { name: '吴亦凡', value: 14263.133233106502 }, { name: 'gai', value: 9743.53957487934 }, { name: 'GAI', value: 8522.66232694265 }, { name: '哈哈哈', value: 7698.80620601334 }, { name: '张靓颖', value: 7492.465254428001 }, { name: '药水', value: 6655.8901403435 }, { name: '凡凡', value: 6632.650433502201 }, { name: '真的', value: 6022.47052337153 }, { name: '可恶', value: 5797.61069876588 }, { name: '感觉', value: 4642.93663210213 }, { name: '凡哥', value: 4554.811271148415 }, { name: '哈哈哈哈', value: 4305.01735446552 }, { name: 'giao', value: 4273.0703677784095 }, { name: '孟子', value: 4055.0087039027 }这个中央孟子坤变成了孟子,哈哈哈哈。 ...

August 20, 2020 · 2 min · jiezi

关于node.js:全民加速节全站加速在互联网媒体应用上的最佳实践

8月19日,全民减速节第三场直播中,阿里云CDN解决方案架构师拓州进行了《全站减速在媒体服务行业的实际》主题分享,针对互联网媒体服务行业中的特色和痛点,介绍阿里云全站减速产品的利用实际。 互联网媒体服务的特色互联网媒体服务平台个别蕴含海量的图文、音视频文件的上传、分享和流传,具备用户量大、用户散布广、实时性要求高、热点突发的业务特色。 首先是内容流传范围广,对CDN的节点笼罩要求高;第二是实时性,平台十分关注文件上传散发的实时性,对CDN的响应效率有较高要求;第三是突发性,平台个别具备热点、流动所带来的流量激增状况,对带宽等响应资源要求较高,对CDN的资源储备和弹性有肯定要求;第四是业务复杂性高,因为媒体服务类平台覆盖范围宽泛,用户群体十分多样化,不同用户的网络环境参差不齐,这就导致平台对网络传输优化要求较高。 在上述背景下,传统的源站单IP接入模式无奈满足高牢靠、高效率、大并发的业务场景,须要依附DCDN产品解决。 阿里云DCDN技术特点针对媒体服务类平台的痛点,DCDN产品能够在节点笼罩和稳固高效两个方面提供解决方案。 首先,DCDN节点的覆盖范围十分宽泛,在中国内陆就领有超过2300个节点,笼罩31个省级区域,并且大量的节点位于省会等一线城市,也就是网络环境以及品质都比拟好的区域。另外在海内领有超过500多节点,笼罩超过70个国家和区域。 其次,DCDN产品十分稳固高效,基于短缺的节点以及带宽的保障,反对亿级QPS并发,可能提供稳固的减速服务;具备先进的分布式系统架构,可能实现全网的负载平衡,保障节点的可用性;通过优化的传输协定,能够反对HTTP/2高效的传输协定,可能实现疾速稳固的数据传输;另外,DCDN具备精准缓存、高速缓存、高速读写、高效回源以及智能调度的能力,全面保障成果稳固。 DCDN在游戏行业的案例利用一、视频、图片文件上传到源站减速第一个案例是媒体类客户的文件上传到源站场景下,如何进行减速。通常媒体平台的业务场景分为文件生产上传以及文件散发,在文件上传场景下,对网络的环境要求比拟高,会受到公网的稳定以及长传抖动等绝对不可控因素的影响,造成速率慢、传输的成功率低等相干的问题。 在某客户采纳阿里云DCDN上传之后,上传的效率能够晋升超过50%,同时,DCDN反对最大2G文件的上传。如下图所示,某客户通过DCDN减速以及没有通过DCDN减速上传文件的上传速率的比照状况。图中蓝色局部上传速率有超过60%的晋升,能够达到1500kb/s以上,而绿色的未通过DCDN减速的上传速率落在300~500以及500~1000kb的区间内。所以,DCDN对上传速率及用户体验晋升成果非常显著。 二、用户散布及网络环境简单状况下的申请成功率晋升在用户散布及网络环境都比较复杂的状况下,用户申请的失败率比拟高。如下图所示,某客户源站看到的用户申请失败数的统计状况,在没有通过DCDN减速之前,申请失败数更多的落在15~20区间内,通过DCDN产品减速之后,相干的申请失败数能够很显著着落到个位数,相干用户申请的失败率升高超过80%,收益的次要起源是在于DCDN产品具备智能的路由抉择的性能,会实时探测以后网络最优的链路环境,在用户申请的时候给予最优的门路保障,能够晋升DCDN外部链路的稳定性,保障申请的成功率。 三、重大流动,超千万并发申请当媒体服务平台有热点突发以及有重大流动时,源站的负载能力有余,不足以撑持如此大的流动,就可能无奈保障流动顺利进行。此时能够通过接入阿里云DCDN产品,通过动动态的拆散,实现动态文件的缓存,这样能够很大水平升高一部分源站的负载能力,并且动静回源局部,也反对通过HTTP/2协定回源,能够升高源站链接的负载数,晋升链接的复用率,能够很好的解决源站负载能力有余的问题。通过DCDN短缺的冗余资源,能够完满地承接重大的流动。 DCDN更多利用DCDN产品还有很多扩大的利用,次要介绍4个方面。 第一,DCDN反对IP利用减速,这是非规范的HTTP协定用户的层面的一种减速。利用于4层的cell协定服务的场景。当有一些业务在减速的过程中,能够疏忽利用层面,不须要进行利用层面的解决,而只进行网络减速,能够抉择IP利用减速。 第二,DCDN产品反对websocket的协定,在用户到CDN节点以及CDN节点到源站之间建设全双工的通信,能够放弃短暂的链接,这样用户在第二次发动申请的时候,就不须要再次建设链接,能够晋升用户的用户体验。 第三,DCDN反对源站的主动切换,通常的源站会有主备两个原站,当主源站呈现响应以及可用性方面的问题,DCDN实时探测会及时发现异常情况,将有问题的原站进行剔除,申请会拜访到备用的源站,这样能够最大水平地保障用户层面的稳定性。 第四,DCDN反对Ipv6的拜访,目前IPv6曾经笼罩三大运营商,除此以外,阿里的DCDN产品还有更多的相干的利用能够摸索,详情能够登录官网全站减速产品详情理解状况。 原文链接 本文为阿里云原创内容,未经容许不得转载。

August 20, 2020 · 1 min · jiezi

关于node.js:使用Hexo框架10分钟搭建个人博客

首先是先给大家打个招呼最近看网上看到了很多的的对于搭建博客的视频,我本人也学着本人搭建了一个博客"我本人的博客链接"(欢送大家来我的博客跟我深刻交♂流),明天我把搭建的过程记录下来写成博客,留下一个留念,也能够顺便帮忙那些想要搭建集体博客的小伙伴们,帮忙他们搭建属于本人的博客主页啦,那么废话不多说,当初就开始吧。 环境搭建与装置第一步:装置node.jsnodejs下载地址进入链接地址后点击下载长期反对版。 进入后依照你们本人的零碎抉择安装包,我这里==应用的是win10零碎==,不过mac零碎的也能够持续看上来,因为==这两个零碎在下文将会应用到的指令十分的相像==,我也会指出那些不一样的中央 下载完之后进行装置,node.js的装置非常简单,只须要始终点击下一步就好了 留神在最初时,==装置实现会你会留神到给出的两个地址==,在安装包其中它不仅下载了==node.js自身==,还装置了一个是==npm包管理器==,而这个它是下文咱们应用hexo搭建博客必须应用到的货色。 win + R 关上运行,输出cmd 进入终端输出node, 如果装置胜利则会显示其版本号 那么到这里可能你们会有疑难了,为什么要下载node.js,下面干这么多事件有什么用呢??!这是因为hexo是在node.js上生成的,所以当咱们真正的要开始装置hexo的时候,后面这两个货色是必不可少的 接下来咱们就会应用到刚刚装置的npm包管理器来下载hexo了,因为国内镜像源的速度很慢,所以咱们先应用npm来装置一个==cnpm==,这是一个淘宝的镜像源,应用阐明能够看这里链接。不过我也会在上面说怎么下载。 在终端里输出 : npm install -g cnpm --registry=https//registry.npm.taobao.org敲击回车键即可开始下载了。 当装置好cnpm,能够应用下面测试node.js和npm那样的办法,输出cnpm这样的话cnpm也装置好了,接下来就借助cnpm来装置hexo了 在终端输出 cnpm install -g hexo-cli敲击回车键后就会开始下载。 当装置实现后,咱们持续应用 hexo -v来验证一下装置是否胜利好了hexo博客曾经装置好了,咱们曾经离胜利不到一半的间隔了 那么咱们接下来就要为咱们的博客建设一个新的文件夹来寄存咱们所有的配置文件和博客文章了。 输出 md blog即可在当前目录下创立一个叫blog的文件夹,当然你如果想要去其余的名字,把blog改掉就好了。这时关上文件夹,找到方才的目录,你就能够找到刚刚建设的blog文件夹 当然更简略的办法,就间接在文件管理器外面右键新建文件夹即可创立。 初始化博客终端里输出 cd blog进入刚刚新建的文件夹 window 零碎里间接输出 hexo init如果是mac零碎则输出 sudo hexo init回车即可开始初始化 初始化实现后 Window零碎输出 dir查看一下装置初始化实现后,文件夹内都生成了什么货色而mac零碎输出 ls -l即可查看 这些货色咱们也能够在文件管理器中间接看到 这些都是hexo为你主动生成的一些最根底的博客框架的货色 启动hexo博客这时候咱们所有都筹备好了当前,在blog文件夹目录下终端输出 hexo s即可启动hexo==(tips: hexo s 即为 hexo server)==你会看到以下这时它就主动为你在本地4000的端口下面启动了hexo,这时候复制该网址,输出到浏览器外面就能够拜访到咱们刚生成的博客。这个时候你的博客就曾经搭建好了。 并且下面本人附带了一篇文章叫Hello world,外面教你了如何新建文章和一些基本操作。 新建文章的语法是:在终端cd到博客的文件夹的目录内输出 hexo new "你的博客名字"这时候它会提醒你的这篇新文章的目录地址,上图即为 ...

August 18, 2020 · 1 min · jiezi

关于node.js:eggjs-原理解析

Egg.js 介绍基于Koa的企业级三层构造框架 Egg.js 的构造三层构造 信息资源层裸露给里面的接口,后端对其余服务的裸露,蕴含 视图、接口;业务逻辑层反复的业务逻辑解决放在外面,实现外围的业务管制也是在这一层实现。数据拜访层重点负责数据库拜访,实现长久化性能我的项目构造Egg-Dome├──app ├────controller #路由对应的加载文件├────public #寄存动态资源├────service #反复的业务逻辑解决├────router.js #门路匹配├──config #配置文件根本应用 app/controller/product.jsconst {Controller} = require('egg')class ProductController extends Controller { async index(){ const {ctx} = this const res = await ctx.service.product.getAll() ctx.body=res }app/service/product.jsconst {Service} = require('egg');class ProductService extends Service{ async getAll(){ return { id: 1, name: '测试数据' } }}module.exports = ProductServiceapp/router.js 'use strict';/** * @param {Egg.Application} app - egg application */module.exports = app => { const { router, controller } = app; router.get('/product',controller.product.index)};创立模型层egg.js 加载任何性能都是基于插件以mysql + sequelize为例例演示数据长久化装置: ...

August 17, 2020 · 5 min · jiezi

关于node.js:译使用频率最高的前30个Nodejs面试问题-の-0110

作者 • Dhanjiv Pandey • 本文出处 • 已取得中译受权• 作者twitter• 译者主页 译者按: 2018年的文章,其中局部问题放在明天依然不算过期。# Q-01:什么是Node.js?简略的说 Node.js 就是运行在服务端的 JavaScript。 是一个基于Chrome JavaScript 运行时建设的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度十分快,性能十分好。 Node.js是单线程的,它采纳基于事件循环的并发模型。它不会阻塞代码运行 (译者:非阻塞I/O模型) ,而是注册一个容许应用程序持续运行的回调。这意味着Node.js能够解决并发操作而无需创立多个执行线程,因而能够很好地扩大 (译者:解决并发操作和扩大有什么间接关系?)。 是构建运行在分布式设施上的数据密集型实时程序的完满抉择。 以下是应用Node.js的最佳畛域: 调用I/O的应用程序数据流利用数据密集型实时应用程序(DIRT)(译者:DIRT是啥?)基于JSON API的应用程序单页利用(SPA)同时,它不适宜那些占用较多CPU使用量的大型应用程序。 # Q-02:Node.js的次要性能是什么?让咱们看一下Node.js的一些要害性能。 异步事件驱动的IO有助于解决并发申请 —— Node.js的所有API都是异步的。此性能意味着,如果Node.js 收到对某些Input/Output操作的申请,它将在后盾执行该操作并持续解决其余申请,而无需期待先前申请的响应后果。代码执行速度更快 —— Node.js应用V8 JavaScript引擎,就是 Google Chrome 应用的那个。Node在JavaScript引擎上有一个包装器,这使得V8引擎更快,因而Node.js中的申请解决也更快 (译者:Node原来这么酷吗?I了I了)。单线程但高度可扩大 —— Node.js应用单线程模型进行事件循环。这些事件的响应可能会或可能不会立刻达到服务器。然而,这不会阻止其余操作。从而使Node.js具备高度可扩展性。传统服务器创立无限的线程来解决申请,而Node.js创立一个线程来为大量的此类申请提供服务。Node.js库应用JavaScript语法 —— 从开发人员的角度来看,这是Node.js的另一个重要性能。大多数开发人员曾经精通JavaScript。因而,对于相熟JavaScript的开发人员而言,Node.js中的开发变得更加容易。Node.js有一个沉闷的、充满活力的社区 —— 沉闷的社区总是让Node.js跟上web开发的最新趋势。No Buffering —— Node.js应用程序从不缓冲任何数据。他们只是简略地以块的模式输入数据 (译者:Buffering是缓冲的意思吧?)。# Q-02:请阐明咱们何时应用Node.js,何时不应用它?咱们什么时候应该应用Node.js? 应用Node.js来开发流媒体或基于事件的实时应用程序是十分现实的,这些应用程序须要更少的CPU应用,比方: 聊天应用程序。游戏服务器。Node.js非常适合须要同时解决数千个用户申请的服务。 适宜协同环境。 It is suitable for environments where multiple people work together. For example, they post their documents, modify them by doing check-out and check-in of these documents. 它实用于多人一起工作的环境。例如,他们公布其文档,通过检出和检入这些文档来对其进行批改 (译者:这句话没有了解)。 Node.js通过为文档的每次更改创立一个事件循环来反对这种状况。Node.js的“事件循环”性能使它能够同时解决多个事件而不会被阻塞。广告服务器。 同样,咱们的服务器能够解决数千个从地方主机下载广告的申请。Node.js是解决此类工作的现实解决方案。流媒体服务器。 应用Node.js的另一种现实计划是用于多媒体流服务器,客户端向服务器发出请求,从服务器上下载不同的多媒体内容。。 总而言之,当您须要高级别的并发性但须要占用CPU更少的工夫时,最好应用Node.js。 最初但并非最不重要的一点,因为Node.js外部应用JavaScript,所以它最适宜于构建也应用JavaScript的客户端应用程序。何时不应用Node.js? ...

August 16, 2020 · 1 min · jiezi

关于node.js:译使用频率最高的前30个Nodejs面试问题-の-0110

作者 • Dhanjiv Pandey • 本文出处 • 已取得中译受权• 作者twitter• 译者主页 译者按: 2018年的文章,其中局部问题放在明天依然不算过期。# Q-01:什么是Node.js?简略的说 Node.js 就是运行在服务端的 JavaScript。 是一个基于Chrome JavaScript 运行时建设的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度十分快,性能十分好。 Node.js是单线程的,它采纳基于事件循环的并发模型。它不会阻塞代码运行 (译者:非阻塞I/O模型) ,而是注册一个容许应用程序持续运行的回调。这意味着Node.js能够解决并发操作而无需创立多个执行线程,因而能够很好地扩大 (译者:解决并发操作和扩大有什么间接关系?)。 是构建运行在分布式设施上的数据密集型实时程序的完满抉择。 以下是应用Node.js的最佳畛域: 调用I/O的应用程序数据流利用数据密集型实时应用程序(DIRT)(译者:DIRT是啥?)基于JSON API的应用程序单页利用(SPA)同时,它不适宜那些占用较多CPU使用量的大型应用程序。 # Q-02:Node.js的次要性能是什么?让咱们看一下Node.js的一些要害性能。 异步事件驱动的IO有助于解决并发申请 —— Node.js的所有API都是异步的。此性能意味着,如果Node.js 收到对某些Input/Output操作的申请,它将在后盾执行该操作并持续解决其余申请,而无需期待先前申请的响应后果。代码执行速度更快 —— Node.js应用V8 JavaScript引擎,就是 Google Chrome 应用的那个。Node在JavaScript引擎上有一个包装器,这使得V8引擎更快,因而Node.js中的申请解决也更快 (译者:Node原来这么酷吗?I了I了)。单线程但高度可扩大 —— Node.js应用单线程模型进行事件循环。这些事件的响应可能会或可能不会立刻达到服务器。然而,这不会阻止其余操作。从而使Node.js具备高度可扩展性。传统服务器创立无限的线程来解决申请,而Node.js创立一个线程来为大量的此类申请提供服务。Node.js库应用JavaScript语法 —— 从开发人员的角度来看,这是Node.js的另一个重要性能。大多数开发人员曾经精通JavaScript。因而,对于相熟JavaScript的开发人员而言,Node.js中的开发变得更加容易。Node.js有一个沉闷的、充满活力的社区 —— 沉闷的社区总是让Node.js跟上web开发的最新趋势。No Buffering —— Node.js应用程序从不缓冲任何数据。他们只是简略地以块的模式输入数据 (译者:Buffering是缓冲的意思吧?)。# Q-02:请阐明咱们何时应用Node.js,何时不应用它?咱们什么时候应该应用Node.js? 应用Node.js来开发流媒体或基于事件的实时应用程序是十分现实的,这些应用程序须要更少的CPU应用,比方: 聊天应用程序。游戏服务器。Node.js非常适合须要同时解决数千个用户申请的服务。 适宜协同环境。 It is suitable for environments where multiple people work together. For example, they post their documents, modify them by doing check-out and check-in of these documents. 它实用于多人一起工作的环境。例如,他们公布其文档,通过检出和检入这些文档来对其进行批改 (译者:这句话没有了解)。 Node.js通过为文档的每次更改创立一个事件循环来反对这种状况。Node.js的“事件循环”性能使它能够同时解决多个事件而不会被阻塞。广告服务器。 同样,咱们的服务器能够解决数千个从地方主机下载广告的申请。Node.js是解决此类工作的现实解决方案。流媒体服务器。 应用Node.js的另一种现实计划是用于多媒体流服务器,客户端向服务器发出请求,从服务器上下载不同的多媒体内容。。 总而言之,当您须要高级别的并发性但须要占用CPU更少的工夫时,最好应用Node.js。 最初但并非最不重要的一点,因为Node.js外部应用JavaScript,所以它最适宜于构建也应用JavaScript的客户端应用程序。何时不应用Node.js? ...

August 16, 2020 · 1 min · jiezi

关于node.js:mysql的安装与使用

下载链接:https://dev.mysql.com/downloads/mysql/2.解压到指标门路3.创立配置文件my.ini4.配置环境变量右击此电脑 -> 属性 ->高级零碎设置 -> 环境变量 -> Path -> 编辑,增加bin目录5.开始装置关上cmd,输出命令:a.mysqld --initialize-insecure --user=mysqlb.mysqld -install呈现提醒 Service successfully installed 表示装置实现6.启动mysqla.配置net环境变量 %SystemRoot%system32b.net start mysql7.mysql -u root -p Enter password可设置数据库明码也可不设置间接enter进入mysql >8.mysql差用命令mysqladmin --version

August 16, 2020 · 1 min · jiezi

关于node.js:mysql的安装与使用

下载链接:https://dev.mysql.com/downloads/mysql/2.解压到指标门路3.创立配置文件my.ini4.配置环境变量右击此电脑 -> 属性 ->高级零碎设置 -> 环境变量 -> Path -> 编辑,增加bin目录5.开始装置关上cmd,输出命令:a.mysqld --initialize-insecure --user=mysqlb.mysqld -install呈现提醒 Service successfully installed 表示装置实现6.启动mysqla.配置net环境变量 %SystemRoot%system32b.net start mysql7.mysql -u root -p Enter password可设置数据库明码也可不设置间接enter进入mysql >8.mysql差用命令mysqladmin --version

August 16, 2020 · 1 min · jiezi

关于node.js:升级Node版本RN项目运行报错cbapply-is-not-a-function

今日打算装置一下ReactNative官网举荐的脚手架工具Ignite。Ignite是一套整合了 Redux 以及一些常见 UI 组件的脚手架。它带有一个命令行能够生成 app、组件或是容器。在装置的过程中,提醒以后零碎装置的node版本过低,无奈装置,于是就想降级一下node的版本。因为零碎中早就装置了node的管理器nvm,所以应用了nvm来降级node的版本@[toc] node版本升级1.查看能够装置的node版本nvm ls-remote 2.抉择一个版本进行装置nvm install v12.18.33.查看已装置的版本nvm ls 遇到报错放心会影响原有我的项目,所以编译启动了以后我的项目,编译build success,完满,but,APP启动间接就把报错了。package服务间接提醒了如下谬误: Loading dependency graph, done. DELTA [android, dev] ../../index.js ░░░░░░░░░░░░░░░░ 0.0% (0/1)/Users/fantuan/ares/node_modules/graceful-fs/polyfills.js:285 if (cb) cb.apply(this, arguments) ^TypeError: cb.apply is not a function at /Users/fantuan/ares/node_modules/graceful-fs/polyfills.js:285:20 at FSReqCallback.oncomplete (fs.js:169:5)Process terminated. Press <enter> to close the window之前我的项目开中并未遇到此类问题,影响了我的工作,只能通过去github上寻求答案咯。 查找问题所在查看报错的源码,在node_module/graceful-fs/polyfills.js的285行看正文应该用来解决旧版本的问题,查看这个办法的调用地位发现在61-63行 解决问题对于咱们来说,既然是旧版的问题,咱们就不必关怀了,间接把调用的办法正文调就行了。敞开package服务,重新启动我的项目就一切正常了。 PS: 查阅node.js的github上issues过程中,发现12.18.3这个版本貌似的确有些问题相干的issues:2874、2871、34529 、34491感兴趣的敌人能够看看。 遇到问题不可怕,面对它解决它,你就又晋升了本人。 感觉文章不错的,给我点个赞哇,关注一下呗! 技术交换可关注微信公众号【君伟说】,加我好友一起探讨 微信交换群:加好友wayne214(备注技术交换)邀你入群,抱团学习共提高

August 11, 2020 · 1 min · jiezi

关于node.js:如何优雅的在项目中设置多个环境变量

总所周知我的项目实现当前代码都会对立打包上线,有些时候咱们须要同时上线不同环境,对于不同的环境咱们所展现页面、性能有时会有很大变动,那么咱们如何应答这样的变动呢? 问题我发现有些琐碎的事件有些琐碎并且很难做,而在Web应用程序外部却是如此。这些事件之一是解决不同的环境变量。 当您仍在开发应用程序时,通常只有一个环境是失常的,然而当其余一些用户开始对其进行测试或要公布它时,您可能心愿对API应用不同的URL,例如该API的开发版本。能够拜访新端点或更全面的记录器以及生产就绪版本的API,这些API通过了良好的测试,并具备发行版本的生产数据库。有时您须要两个以上的环境,例如: 开发:这是您开发应用程序所有新性能的中央;该环境已准备就绪,能够帮忙您取得更好的日志和伪造的数据库,如果您破费很多,能够随时删除并从新创立它们;生产版:这是您将公布到线上的版本那么如何为不同的环境存储(和应用)不同的变量呢?显然,我尝试向Google寻求答案,然而我发现的解决方案仿佛太艰难或不够灵便。 应用.env就是这个文件,在文件中能够定义咱们须要的配置,而后在我的项目中应用process.env全局变量获取,申明的属性在 vue以及react中都有非凡的命名要求,比方vue中属性名必须以VUE\_APP\_结尾,如VUE_APP_XXX,react则须要以REACT_APP结尾。可怜的是,仿佛最多只能解决两种环境(一种开发和一种发行/生产),并且还具备一些可怕的变量缓存。 更简略的解决方案参照后端配置打包profile的形式。这是我目前正在应用的办法;筹备手指,因为您将须要创立一些新文件。 首先,咱们将所有环境存储在envs文件夹中的JSON文件中。我将为本文创立3个环境(开发,暂存和生产),每个环境将具备不同的API_URL。显然,您能够依据须要增加任意多个变量! envs/development.json { "API\_URL": "https://development.api.com",}envs/staging.json { "API\_URL": "https://staging.api.com", }envs/production.json { "API\_URL": "https://production.api.com", }还在我这儿?当初,咱们将创立一个节点脚本,该脚本将在每次咱们想要切换环境时更改环境文件。 我将其放在脚本文件夹中(在该文件夹中,我还有其余脚本能够主动执行构建过程的其余局部) 脚本/set-environment.js#!/ bin/nodeconst fs = require("fs");//获取传递给节点脚本的环境字符串 const environment = process.argv[2] //读取json文件的内容 const envFileContent = require(`../envs/$ {environment} .json`); //将env.json文件内的json复制到 fs.writeFileSync("env.json", JSON.stringify(envFileContent, undefined, 2));此设置enviroment.js首先,它在一个变量中存储的第一个参数,当你调用脚本,那么它将require外面的文件ENVS具备雷同的名称,最初将创立一个env.json文件蕴含envFileContent内容的根文件夹。 当初咱们能够尝试并调用 节点脚本/set-environment.js开发 ✨MAGIC✨…一个新的env.json文件在正确的地位,能够为您的所有变量提供服务。 另外,您能够在package.json文件中设置一些脚本,以切换环境而无需在终端中键入所有单词:只需键入yarn env:dev即可。 { "name": "您的应用程序名称", "scripts": { "start": "本机开始", "env: staging":"节点脚本/set-environment.js阶段", "env: dev”:"节点脚本/set-environment.js 开发", "env: prod":"节点脚本/set-environment.js, "oduction",... }, "依赖项":{...}, ... }如何在代码中应用新的.env文件当初,您只须要从src/env.json文件导入变量,就能够开始了!???? ...

August 7, 2020 · 1 min · jiezi

关于node.js:node版本管理工具-nvm-基本介绍

1 nvm 是什么nvm和n都是node版本管理工具,解决node各种版本存在不兼容景象,能够在同一台机器上装置和切换不同版本的node的工具。 2 nvm 装置两种形式: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash或者 wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash3 nvm 根本命令3.1 装置最新版本node nvm install node3.2 装置指定版本的node nvm install 6.14.43.3 应用某一个版本的node nvm use 14.7.03.4 列出所有node的版本 nvm list3.5 列出某个版本的node的装置门路 nvm which 5.0

August 7, 2020 · 1 min · jiezi

关于node.js:nvm的配置

nvm的配置nvm的目标是切换版本, nvm list 查看本地下载的版本号*示意正在应用的版本号 nvm install v13 示意下载版本号v13nvm root 示意nvm的目录 通过目录找到settings.txt,并将上面两句话退出到settings.txt目录下`node_mirror: https://npm.taobao.org/mirror... npm_mirror: https://npm.taobao.org/mirror...` nvm use 10.9.0 示意切换版本号node -v查看应用的版本号 在装置时呈现的问题呈现下方的状况是因为 先装置的node,在装置的nvm。在装置nvm之前,须要先卸载node,在装置nvm就能够了。 其余遇到的问题,你们能够抛给我,我给你们看一下。

August 6, 2020 · 1 min · jiezi

关于node.js:express结合multer实现文件上传功能

单文件上传: <!--add.ejs--><form action="/admin/nav/doAdd" method="post" enctype="multipart/form-data"> 题目:<input type="text" name="title" id="title"><br><br> 图片:<input type="file" name="pic" id="pic"><br><br> 形容:<textarea name="desc" id="desc" cols="30" rows="10"></textarea><br><br> <input type="submit" value="提交"></form>// nav.js文件中const express = require('express')const tools = require('../../model/tools')router.post('/doAdd', tools.multer().single('pic'), (req, res) => { // 获取表单传过来的数据 res.send({ body: req.body, file: req.file })})// tools.js工具const multer = require('multer')const path = require('path')const sd = require('silly-datetime')const mkdirp = require('mkdirp')let tools = { /* 封装图片上传 */ multer() { var storage = multer.diskStorage({ // 配置上传的目录 destination: async (req, file, cb) => { // 1. 获取以后日期 20200703 let day = sd.format(new Date(), 'YYYYMMDD') // static/upload/20200703 let dir = path.join('static/upload', day) // 2. 依照日期生成图片存储目录 await mkdirp(dir) // mkdirp是一个异步办法 cb(null, dir) }, // 批改上传后的文件名 filename: function (req, file, cb) { // 获取上传文件的后缀名 let extname = path.extname(file.originalname) cb(null, Date.now() + extname) } }) var upload = multer({ storage: storage }) return upload }, md5() { }}module.exports = tools多文件上传: ...

August 6, 2020 · 1 min · jiezi

关于node.js:入门-eggjs-入门之eggjwt

小小持续学习,这次学习的内容是egg-jwt 相干。 创立egg我的项目这里创立一个egg新我的项目,这里应用的是ts模式。 npm init egg --type=tsnpm install 装置相干的包这里创立并装置实现当前,须要再次初始化俩包,别离为egg-cors与egg-jwt token 生成的验证包 npm install egg-cors egg-jwt --save 配置相干插件这里配置相干的插件 import { EggPlugin } from 'egg';const plugin: EggPlugin = { jwt: { enable: true, package: "egg-jwt" }, cors: { enable: true, package: 'egg-cors', }};export default plugin;配置默认配置文件config.jwt = { secret: "123456"//自定义 token 的加密条件字符串};config.security = { csrf: { enable: false, ignoreJSON: true }, domainWhiteList: ['http://localhost:8080'],//容许拜访接口的白名单};config.cors = { origin:'*', allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'};这里配置实现了相干的默认配置 在根目录申明any类型这里须要在跟目录申明一个any类型,用于前后端发送相干的字符串参数。 ...

August 3, 2020 · 3 min · jiezi

关于node.js:入门-eggjs-入门之eggjwt

小小持续学习,这次学习的内容是egg-jwt 相干。 创立egg我的项目这里创立一个egg新我的项目,这里应用的是ts模式。 npm init egg --type=tsnpm install 装置相干的包这里创立并装置实现当前,须要再次初始化俩包,别离为egg-cors与egg-jwt token 生成的验证包 npm install egg-cors egg-jwt --save 配置相干插件这里配置相干的插件 import { EggPlugin } from 'egg';const plugin: EggPlugin = { jwt: { enable: true, package: "egg-jwt" }, cors: { enable: true, package: 'egg-cors', }};export default plugin;配置默认配置文件config.jwt = { secret: "123456"//自定义 token 的加密条件字符串};config.security = { csrf: { enable: false, ignoreJSON: true }, domainWhiteList: ['http://localhost:8080'],//容许拜访接口的白名单};config.cors = { origin:'*', allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'};这里配置实现了相干的默认配置 在根目录申明any类型这里须要在跟目录申明一个any类型,用于前后端发送相干的字符串参数。 ...

August 3, 2020 · 3 min · jiezi

关于node.js:明知-TypeScript-结合-eggjs-基本使用

小小又进入了学习状态,此时小小因为最近接触了js的相干内容,进而接触了一些ts相干的内容,所以小小本次次要学习的内容是ts。 装置相干依赖这里装置两个依赖,别离为egg和ts 装置ts这里须要确保首先装置了npm相干工具。全局装置ts npm install -g typescript进行全局的测试 $ tsc -vVersion 3.2.2这样就实现了本地全局的ts的装置 装置egg这里实现全局装置egg,并初始化依赖我的项目。创立工作目录 mkdir showcase && cd showcase装置相干的依赖 npm init egg --type=ts装置依赖 npm i运行我的项目 npm run dev呈现以下提醒,即代表曾经启动,并装置实现 C:\Users\Administrator\Desktop\untitled4555\ming>npm run dev> ming@1.0.0 dev C:\Users\Administrator\Desktop\untitled4555\ming> egg-bin dev[egg-ts-helper] create typings\app\controller\index.d.ts (5ms)[egg-ts-helper] create typings\config\index.d.ts (16ms)[egg-ts-helper] create typings\config\plugin.d.ts (10ms)[egg-ts-helper] create typings\app\service\index.d.ts (5ms)[egg-ts-helper] create typings\app\index.d.ts (2ms)2020-07-31 14:27:49,701 INFO 12416 [master] node version v13.11.02020-07-31 14:27:49,703 INFO 12416 [master] egg version 2.27.02020-07-31 14:27:59,512 INFO 12416 [master] agent_worker#1:28076 started (9799ms)2020-07-31 14:28:10,469 INFO 12416 [master] egg started on http://127.0.0.1:7001 (20765ms) ...

August 3, 2020 · 3 min · jiezi

关于node.js:学习-Nodejs-之定时任务

小小又开始进入学习状态,小小本次学习的内容是 Node.js 的定时工作。 这里对于Node.js 应用的是node-schedule定时器。所以这里总体是对node-schedule包的相干的学习。 装置应用npm装置相干的包 npm install node-schedule --save或者 yarn add node-schedule应用案例对于定时器来说,应用的通通是Cron格调的定时器。 const schedule = require('node-schedule');const scheduleCronstyle = ()=>{ //每分钟的第30秒定时执行一次: schedule.scheduleJob('30 * * * * *',()=>{ console.log('scheduleCronstyle:' + new Date()); }); }scheduleCronstyle();这里在其回调函数中写入要执行的工作代码,一个定时器就彻底的竣工了 Cron 格调这里对Cron格调进行解释 * * * * * *┬ ┬ ┬ ┬ ┬ ┬│ │ │ │ │ |│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)│ │ │ │ └───── month (1 - 12)│ │ │ └────────── day of month (1 - 31)│ │ └─────────────── hour (0 - 23)│ └──────────────────── minute (0 - 59)└───────────────────────── second (0 - 59, OPTIONAL)从左到右别离代表着 ...

August 3, 2020 · 2 min · jiezi

关于node.js:基于Koa2打造属于自己的MVC框架

Express和Koa作为轻量级的web框架,尽管灵便简略,几行代码就能够启动服务器了,然而随着业务的简单,你很快就会发现,须要本人手动配置各种中间件,并且因为这类web框架并不束缚我的项目的目录构造,因而不同程度的程序员搭出的我的项目品质也是千差万别。为了解决上述问题,社区也呈现了各种基于Express和Koa的下层web框架,比方Egg.js和Nest.js 我目前所在的公司,也是基于Koa并联合本身业务需要,实现了一套MVC开发框架。我司的Node次要是用来承当BFF层,并不波及真正的业务逻辑,因而该框架只是对Koa进行了绝对简略的封装,内置了一些通用的业务组件(比方身份验证,代理转发),通过约定好的目录构造,主动注入路由和一些全局办法 最近摸鱼工夫把该框架的源码简略看了一遍,播种还是很大,于是决定入手实现了一个玩具版的MVC框架 源代码地址 框架应用参考代码-step1 │ app.js│ routes.js│ ├─controllers│ home.js│ ├─middlewares│ index.js│ ├─my-node-mvc # 咱们之后将要实现的框架||├─services│ home.js│ └─views home.html my-node-mvc是之后咱们将要实现的MVC框架,首先咱们来看看最初的应用成果 routes.js const routes = [ { match: '/', controller: 'home.index' }, { match: '/list', controller: 'home.fetchList', method: 'post' }];module.exports = routes;middlewares/index.js const middleware = () => { return async (context, next) => { console.log('自定义中间件'); await next() }}module.exports = [middleware()];app.js const { App } = require('./my-node-mvc');const routes = require('./routes');const middlewares = require('./middlewares');const app = new App({ routes, middlewares,});app.listen(4445, () => { console.log('app start at: http://localhost:4445');})my-node-mvc裸露了一个App类,咱们通过传入routes和middlewares两个参数,来通知框架如何渲染路由和启动中间件 ...

August 3, 2020 · 7 min · jiezi

关于node.js:node文档记录Assertion

node Assertion 断言断言模式node的断言分为严格模式和非严格模式,这两者在应用和log展现上有不同之处(略)集体举荐应用严格模式,信息展现更加清晰引入形式: //严格模式const assert = require('assert').strict;//非严格模式const assert = require('assert');抛出谬误(Class: assert.AssertionError)继承于<errors.Error> -- 参数 message [<string>]actual [<any>]expected [<any>]operator [<string>]stackStartFn [<Function>]method办法分为3类一、 单个值的断言 assert(value[, message]) === assert.ok(value[, message]) //是truthy时通过assert.doseNotMatch(String,regexp[,message]) //正则不匹配字符串时通过assert.match(string, regexp[, message]) //正则匹配字符串时通过assert.ifError(value) //是null或者undefined时通过留神点: doseNotMatch和match的匹配值必须是String(感觉很弱);ifError的值不是判断falsly值;二、 两个值的断言 assert.deepStrictEqual(actual, expected[, message]) //合乎SameValue Comparison准则,援用类型可比拟assert.notDeepStrictEqual(actual, expected[, message])//合乎SameValue Comparison准则,援用类型可比拟assert.strictEqual(actual, expected[, message])//合乎SameValue Comparison准则,援用类型不可比拟assert.notStrictEqual(actual, expected[, message])//合乎SameValue Comparison准则,援用类型不可比拟留神点: 不可比拟的意思是必须是同一个援用地址才雷同,比拟不同援用类型时报错;比拟的办法在最初面;参数别离是理论值,期望值,当产生谬误时的message|error;三、对函数的断言 assert.rejects(asyncFn[, error][, message]) //异步函数断言,当reject没有产生时触发assert.throws(fn[, error][, message]) //同步函数断言,当函数没有抛出谬误时触发assert.doesNotReject(asyncFn[, error][, message])//异步函数断言,当reject触发assert.doesNotThrow(fn[, error][, message])//同步函数断言,抛出谬误时触发留神点: 如果第二个参数传递,且是字符串,而且没有第三个参数的时候,会将第二个参数作为message的传参;官网说前面两个断言的意义不大的起因,集体认为是因为当函数抛出谬误的时候断言也抛出谬误,与其在断言assert中解决这个谬误,不如间接在函数逻辑中解决更为间接;error参数必须和函数抛出的谬误相匹配,也就是说判断抛出的谬误必须蕴含error参数,不然报错。能够想到这种断言能够断言两种状况,即是否产生断言,而产生断言后抛出的谬误是否与预期的error相匹配(当有嵌套的对象时,嵌套的对象构造必须是预期和理论一样能力通过);//以官网例子为准,此时能通过const err = new TypeError('谬误值');err.code = 404;err.foo = 'bar';err.info = { nested: true, baz: 'text'};err.reg = /abc/i; assert.throws( () => { throw err; }, { name: 'TypeError', message: '谬误值', info: { nested: true, baz: 'text' } });//谬误, 因为断言的对象上不存在aconst err = new TypeError('谬误值');err.code = 404;err.foo = 'bar';err.info = { nested: true, baz: 'text'};err.reg = /abc/i; assert.throws( () => { throw err; }, { name: 'TypeError', message: '谬误值', info: { nested: true, baz: 'text' }, a:1 });//正确,尽管断言上的属性没有a,然而其余属性都能通过测验const err = new TypeError('谬误值');err.code = 404;err.foo = 'bar';err.a = 1err.info = { nested: true, baz: 'text'};err.reg = /abc/i; assert.throws( () => { throw err; }, { name: 'TypeError', message: '谬误值', info: { nested: true, baz: 'text' } });严格相等的规定1.根底类型的比拟应用Object.is()比拟; ...

August 2, 2020 · 2 min · jiezi

关于node.js:NodejsRedis实现消息队列的最佳实践

问题来由最近在开发一个小型前端监控我的项目,因为技术栈中应用到了 Node + Redis 作为音讯队列实现,因而这里记录下在 Node 中通过 Redis 来实现音讯队列时的 应用办法 和 注意事项 什么是音讯队列音讯队列,是一种寄存 音讯 是队列构造,能够用来解决 分布式系统通信 从而解耦零碎模块、异步工作解决、申请消峰限流的问题。 既然叫做队列,那它个别是从一侧推入音讯,从另一侧生产音讯;大略是如下的流程。 在我的需要当中,我用音讯队列来做异步的入库解决。 我通过 Node 做了一个对外的日志接管层(即图中 Koa Server)用于接管上报日志,当Koa Server接管实现会立刻给用户响应 OK,因为用户是没必要去感知后端日志的入库后果的。 因而 Koa Server 收到日志后,将音讯放入 Redis 音讯队列即可。另外一端,我启动了一个 生产 程序(即上图中的日志入库模块,它也是一个 Node 脚本)来对MQ音讯进行读取并进行入库操作。 Redis 如何做音讯队列音讯队列,其实有 2种类型。一种是基于 队列模型 的,一种是基于 订阅公布模式的。 对于 订阅公布模式 来说,是指的多个消费者都能够订阅某一个 channel 的音讯,当channel中来了音讯,所有的订阅者都会收到告诉,并且所有的订阅者都能够对同一个音讯进行解决(生产)。 对于 队列模型 来说,当音讯入队后,在另一端只出队一次,如果有多个消费者在期待这个队列,那么只有一个消费者能拿到这个音讯进行解决。 在 Redis 中,以上 2 种模型,别离通过 pub/sub 性能和 list 构造能够来实现。 对于我的日志接管场景来说,我冀望的是无论我后端有多少个 入库消费者,我心愿同一条上报只能入库一次。因而对我来说,我须要应用 队列模型 来实现音讯队列,即应用 Redis 的 List 构造。 ...

August 1, 2020 · 3 min · jiezi

关于node.js:NodejsRedis实现消息队列的最佳实践

问题来由最近在开发一个小型前端监控我的项目,因为技术栈中应用到了 Node + Redis 作为音讯队列实现,因而这里记录下在 Node 中通过 Redis 来实现音讯队列时的 应用办法 和 注意事项 什么是音讯队列音讯队列,是一种寄存 音讯 是队列构造,能够用来解决 分布式系统通信 从而解耦零碎模块、异步工作解决、申请消峰限流的问题。 既然叫做队列,那它个别是从一侧推入音讯,从另一侧生产音讯;大略是如下的流程。 在我的需要当中,我用音讯队列来做异步的入库解决。 我通过 Node 做了一个对外的日志接管层(即图中 Koa Server)用于接管上报日志,当Koa Server接管实现会立刻给用户响应 OK,因为用户是没必要去感知后端日志的入库后果的。 因而 Koa Server 收到日志后,将音讯放入 Redis 音讯队列即可。另外一端,我启动了一个 生产 程序(即上图中的日志入库模块,它也是一个 Node 脚本)来对MQ音讯进行读取并进行入库操作。 Redis 如何做音讯队列音讯队列,其实有 2种类型。一种是基于 队列模型 的,一种是基于 订阅公布模式的。 对于 订阅公布模式 来说,是指的多个消费者都能够订阅某一个 channel 的音讯,当channel中来了音讯,所有的订阅者都会收到告诉,并且所有的订阅者都能够对同一个音讯进行解决(生产)。 对于 队列模型 来说,当音讯入队后,在另一端只出队一次,如果有多个消费者在期待这个队列,那么只有一个消费者能拿到这个音讯进行解决。 在 Redis 中,以上 2 种模型,别离通过 pub/sub 性能和 list 构造能够来实现。 对于我的日志接管场景来说,我冀望的是无论我后端有多少个 入库消费者,我心愿同一条上报只能入库一次。因而对我来说,我须要应用 队列模型 来实现音讯队列,即应用 Redis 的 List 构造。 ...

August 1, 2020 · 3 min · jiezi

关于node.js:xlsxpopulate-花式解析excel

最近遇到一个需要:解析 excel 并获取单元格内的色彩。说起解析 excel,不得不提一下SheetJS js-xlsx , github上有22k多Star,性能非常弱小。惋惜,他们是有个免费版的,解析单元格背景色彩的性能并不对我等白嫖用户凋谢。 在我坚定不移的面向程(gu)序(ge)编程下,终于让我发现一个能解决需要的node库 xlsx-populate装置xlsx-populate这个无需多言,关上终端间接输出命令就好 npm install xlsx-populate开始应用创立一个新的excelconst XlsxPopulate = require('xlsx-populate');XlsxPopulate.fromBlankAsync() .then(workbook => { workbook.sheet("Sheet1").cell("A1").value("This is neat!"); return workbook.toFileAsync("./out.xlsx"); }); 解析excelconst XlsxPopulate = require('xlsx-populate');XlsxPopulate.fromFileAsync("./Book1.xlsx") .then(workbook => { const value = workbook.sheet("Sheet1").cell("A1").value(); console.log(value); });下面只是惯例操作,上面来点不一样的 将单元格设置为富文本const RichText = require('xlsx-Populate').RichText;const cell = workbook.sheet(0).cell('A1');cell.value(new RichText()); cell.value() .add('hello ', { italic: true, bold: true }) .add('world!', { fontColor: 'FF0000' });增加超链接cell.value("Link Text") .style({ fontColor: "0563c1", underline: true }) .hyperlink("http://example.com");获取单元格背景const XlsxPopulate = require('xlsx-populate');XlsxPopulate.fromFileAsync("./Book1.xlsx") .then(workbook => { const background = workbook.sheet("Sheet1").cell("A1").style("fill"); console.log(background); });其中style(value)可选的参数十分多 style参数 ,根本的款式都可能获取的到应用分享上面是我利用xlsx-populate解析excel的代码XlsxPopulate.fromFileAsync(newPath) .then(workbook => { var sheet = workbook.sheet(0) var rows = sheet._rows let resultData = { tableHead: [], tableData: [] } let tableId = [] rows.forEach(row => { row._cells.forEach(cell => { let col = cell.columnNumber() let row = cell.rowNumber() if(row == 1 && cell.value()){ let value = cell.value() resultData.tableHead.push(value) } let backgroundCR = cell.columnName() + row let background = workbook.sheet("Sheet1").cell(backgroundCR).style("fill") let bg if(background){ bg = background.color != undefined ? '#' + workbook.sheet("Sheet1").cell(backgroundCR).style("fill").color.rgb.substring(2) : null }else{ bg = null } if(tableId.indexOf(row) == -1 && row != 1){ let resultDataItem = [{ columnNumber: col, rowNumber: row, background: bg, value: cell.value() || "none" }] resultData.tableData.push(resultDataItem) tableId.push(row) }else if(tableId.indexOf(row) != -1 && row != 1){ let resultDataItem = { columnNumber: col, rowNumber: row, background: bg, value: cell.value() || "none" } resultData.tableData[row - 2].push(resultDataItem) } }) }) }).catch( error => { console.log(error) });

July 31, 2020 · 2 min · jiezi

关于node.js:npm的依赖与版本

npm的依赖与版本在日常开发中咱们应用中心化的package.json配置文件来保护我的项目的配置信息(比方名称、版本、许可证等元数据)以及依赖模块 依赖类型目前反对以下5种 dependenciesdevDependenciespeerDependenciesoptionalDependenciesbundledDependencies/bundleDependencies示例 { "name": "quanerp-pc-v4", "version": "4.0.0", "private": true, "dependencies": { "react": "^16.13.0", "rxjs": "^6.5.4" }, "devDependencies": { "cross-env": "^7.0.2", "eslint": "^6.8.0", "mockjs": "^1.1.0", }, "peerDependencies": {}, "optionalDependencies": {}, "bundledDependencies": [],}dependencies运行我的项目的依赖,打包公布后执行所须要的npm install packageName --save# 或者npm install packageName -SdevDependencies开发模式下的依赖,只利用于开发环境,打包后的文件中不蕴含npm install packageName --save-dev# 或者npm install packageName -DpeerDependencies等同(伙伴)依赖第一次见到的时候我也懵懵的,从字面意思上很难了解 它的作用咱们来举个栗子阐明 我写了个npm包vue-element-utils它的作用是对 element-ui 做了一些自定义指定的拓展工具,如果我在没有下载安装 element-ui 之前就应用那么就会报错。 这里咱们给peerDependencies退出 element-ui,它在下载时会判断以后依赖中是否有 element-ui 如果没有则将申明的依赖装置进来,如果有则疏忽 peerDependencies 中的申明 还能够解决外围依赖库被反复下载的问题。 npm v3 中移除了peerDependencies,外部做了优化,将依赖的树形构造做了扁平化解决。 npm v3 中,依赖树的生成会尽量的扁平,相应 peerDependencies 的行为有所变动。 peerDependencies 中申明的依赖,如果我的项目没有显式依赖并装置,则不会被 npm 主动装置,转而输入 warning 日志 ...

July 30, 2020 · 1 min · jiezi

关于node.js:关于nodejs上传文件到七牛浏览器无法解析css

应用nodejs 上传文件到七牛对象存储中,文件类型蕴含html、css、js、json、image等格局,其中json、css文件类型mimeType均被转为html/text格局,找到问题申请七牛相干反对后,解决办法如下: 在上传代码中增加下述内容:每次将mimeType参数重置下 ...var putExtra = new qiniu.form_up.PutExtra();// putExtra.mimeType = null;...fileList.forEach(() => { putExtra.mimeType = null;})留神!!!若调用循环上传,则需每次都在循环中重置mimeType

July 28, 2020 · 1 min · jiezi

关于node.js:nestjsvuets打造一个酷炫的星空聊天室

我的项目界面 我的项目地址点击链接能够看到我的项目的gif图github: https://github.com/genaller/g... 我的项目形容前端: vue+vue-router+vuex+socket.io+typescript 后端: nestjs+nestjs/websocket+typescript 性能介绍更改用户名/头像上传群聊/私聊新增群/退出群聊/含糊搜寻群增加好友/含糊搜寻好友表情包音讯分页环境配置数据库mysql 以及 chat数据库node v10.16.3运行我的项目前端我的项目 cd genal-chat-client npm run serve后端我的项目 cd genal-chat-servernpm run start:dev作者github: edison

July 27, 2020 · 1 min · jiezi