发现 vscode 好像没有 回到上一次编辑的位置 的 这个操作, 不知道有没有用过 eclipse 的朋友
VSCode 快捷键问题,如何实现 Eclipse 中 ctrl + q 回到上一次编辑的位置?
Api测试创建主题
仅仅是个测试哦
爬虫利器 Puppeteer 实战
Puppeteer 介绍
Puppeteer
翻译是操纵木偶的人,利用这个工具,我们能做一个操纵页面的人。Puppeteer
是一个Nodejs
的库,支持调用Chrome的API来操纵Web
,相比较Selenium
或是PhantomJs
,它最大的特点就是它的操作Dom
可以完全在内存中进行模拟既在V8
引擎中处理而不打开浏览器,而且关键是这个是Chrome团队在维护,会拥有更好的兼容性和前景。
Puppeteer
用处
- 利用网页生成PDF、图片
- 爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)
- 可以从网站抓取内容
- 自动化表单提交、UI测试、键盘输入等
- 帮你创建一个最新的自动化测试环境(chrome),可以直接在此运行测试用例6.捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题
Puppeteer 使用
安装 Puppeteer
- 由于封网,直接下载
Chromium
会失败,可以先阻止下载Chromium
然后再手动下载它
# 安装命令
npm i puppeteer --save
# 错误信息
ERROR: Failed to download Chromium r515411! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" env variable to skip download.
# 设置环境变量跳过下载 Chromium
set PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
# 或者可以这样干,只下载模块而不build
npm i --save puppeteer --ignore-scripts
# 成功安装模块
+ puppeteer@0.13.0
added 1 package in 1.77s
- 手动下载 Chromium,下载完后将压缩包解压,会有个
Chromium.app
,将其放在你喜欢的目录下,例如/Users/huqiyang/Documents/project/z/chromium/Chromium.app
。网上说正常安装包后Chromium.app
会在.local-chromium
中,手动下载完只要把Chromium.app
放在.local-chromium
中即可,尝试多遍后不成功,无奈放弃,但这并不影响后续操作。
点击查阅 Puppeteer
API
初试 Puppeteer
,截个图吧
知识点
puppeteer.launch
启动浏览器实例browser.newPage()
创建一个新页面page.goto
进入指定网页page.screenshot
截图
const puppeteer = require('puppeteer');
(async () => {
const browser = await (puppeteer.launch({
// 若是手动下载的chromium需要指定chromium地址, 默认引用地址为 /项目目录/node_modules/puppeteer/.local-chromium/
executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium',
//设置超时时间
timeout: 15000,
//如果是访问https页面 此属性会忽略https错误
ignoreHTTPSErrors: true,
// 打开开发者工具, 当此值为true时, headless总为false
devtools: false,
// 关闭headless模式, 不会打开浏览器
headless: false
}));
const page = await browser.newPage();
await page.goto('https://www.jianshu.com/u/40909ea33e50');
await page.screenshot({
path: 'jianshu.png',
type: 'png',
// quality: 100, 只对jpg有效
fullPage: true,
// 指定区域截图,clip和fullPage两者只能设置一个
// clip: {
// x: 0,
// y: 0,
// width: 1000,
// height: 40
// }
});
browser.close();
})();
运行结果
进阶,获取网易云音乐的歌词和评论
网易云音乐的API经过AES和RSA算法加密,需要携带加密的信息通过POST方式请求才能获取到数据。但
Puppeteer
出现后,这些都不重要了,只要它页面上显示了,通过Puppeteer
都能获取到该元素。
知识点
page.type
获取输入框焦点并输入文字page.keyboard.press
模拟键盘按下某个按键,目前mac上组合键无效为已知bugpage.waitFor
页面等待,可以是时间、某个元素、某个函数page.frames()
获取当前页面所有的iframe
,然后根据iframe
的名字精确获取某个想要的iframe
iframe.$('.srchsongst')
获取iframe
中的某个元素iframe.evaluate()
在浏览器中执行函数,相当于在控制台中执行函数,返回一个Promise
Array.from
将类数组对象转化为对象page.click()
点击一个元素iframe.$eval()
相当于在iframe
中运行document.queryselector
获取指定元素,并将其作为第一个参数传递iframe.$$eval
相当于在iframe
中运行document.querySelectorAll
获取指定元素数组,并将其作为第一个参数传递
const fs = require('fs');
const puppeteer = require('puppeteer');
(async () => {
const browser = await (puppeteer.launch({ executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium', headless: false }));
const page = await browser.newPage();
// 进入页面
await page.goto('https://music.163.com/#');
// 点击搜索框拟人输入 鬼才会想起
const musicName = '鬼才会想';
await page.type('.txt.j-flag', musicName, {delay: 0});
// 回车
await page.keyboard.press('Enter');
// 获取歌曲列表的 iframe
await page.waitFor(2000);
let iframe = await page.frames().find(f => f.name() === 'contentFrame');
const SONG_LS_SELECTOR = await iframe.$('.srchsongst');
// 获取歌曲 鬼才会想起 的地址
const selectedSongHref = await iframe.evaluate(e => {
const songList = Array.from(e.childNodes);
const idx = songList.findIndex(v => v.childNodes[1].innerText.replace(/\s/g, '') === '鬼才会想起');
return songList[idx].childNodes[1].firstChild.firstChild.firstChild.href;
}, SONG_LS_SELECTOR);
// 进入歌曲页面
await page.goto(selectedSongHref);
// 获取歌曲页面嵌套的 iframe
await page.waitFor(2000);
iframe = await page.frames().find(f => f.name() === 'contentFrame');
// 点击 展开按钮
const unfoldButton = await iframe.$('#flag_ctrl');
await unfoldButton.click();
// 获取歌词
const LYRIC_SELECTOR = await iframe.$('#lyric-content');
const lyricCtn = await iframe.evaluate(e => {
return e.innerText;
}, LYRIC_SELECTOR);
console.log(lyricCtn);
// 截图
await page.screenshot({
path: '歌曲.png',
fullPage: true,
});
// 写入文件
let writerStream = fs.createWriteStream('歌词.txt');
writerStream.write(lyricCtn, 'UTF8');
writerStream.end();
// 获取评论数量
const commentCount = await iframe.$eval('.sub.s-fc3', e => e.innerText);
console.log(commentCount);
// 获取评论
const commentList = await iframe.$$eval('.itm', elements => {
const ctn = elements.map(v => {
return v.innerText.replace(/\s/g, '');
});
return ctn;
});
console.log(commentList);
})();
运行结果
高级爬虫
爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染),通俗讲就是在页面上显示的内容我们都能获取到。下面我们就通过爬取
瓜子二手车直卖网
的车辆信息来认识它。
首先通过 axios
来试试
const axios = require('axios');
const useAxios = () => {
axios.get('https://www.guazi.com/hz/buy/')
.then(((result) => {
console.log(result.data);
}))
.catch((err) => {
console.log(err);
});
};
结果它返回给我这个玩意,这显然不是我要的内容
通过 Puppeteer
爬取
const fs = require('fs');
const puppeteer = require('puppeteer');
(async () => {
const browser = await (puppeteer.launch({ executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium', headless: true }));
const page = await browser.newPage();
// 进入页面
await page.goto('https://www.guazi.com/hz/buy/');
// 获取页面标题
let title = await page.title();
console.log(title);
// 获取汽车品牌
const BRANDS_INFO_SELECTOR = '.dd-all.clearfix.js-brand.js-option-hid-info';
const brands = await page.evaluate(sel => {
const ulList = Array.from($(sel).find('ul li p a'));
const ctn = ulList.map(v => {
return v.innerText.replace(/\s/g, '');
});
return ctn;
}, BRANDS_INFO_SELECTOR);
console.log('汽车品牌: ', JSON.stringify(brands));
let writerStream = fs.createWriteStream('car_brands.json');
writerStream.write(JSON.stringify(brands, undefined, 2), 'UTF8');
writerStream.end();
// await bodyHandle.dispose();
// 获取车源列表
const CAR_LIST_SELECTOR = 'ul.carlist';
const carList = await page.evaluate((sel) => {
const catBoxs = Array.from($(sel).find('li a'));
const ctn = catBoxs.map(v => {
const title = $(v).find('h2.t').text();
const subTitle = $(v).find('div.t-i').text().split('|');
return {
title: title,
year: subTitle[0],
milemeter: subTitle[1]
};
});
return ctn;
}, CAR_LIST_SELECTOR);
console.log(`总共${carList.length}辆汽车数据: `, JSON.stringify(carList, undefined, 2));
// 将车辆信息写入文件
writerStream = fs.createWriteStream('car_info_list.json');
writerStream.write(JSON.stringify(carList, undefined, 2), 'UTF8');
writerStream.end();
browser.close();
})();
运行结果
资料
- Puppeteer 官方文档
- 键名映射
- 网上的更多教程:Puppeteer 入门教程、Puppeteer 初探之前端自动化测试、使用puppeteer-autotest 来为cnodejs 做自动化测试.
- 多多关注 Puppeteer 的 issues来解决问题
未完待续,有疑问请留言,大家一起研究
前端的对决:React的JSX与Vue的templates
React.js和Vue.js是这个星球上最流行的JavaScript库。它们都很强大,相对来说很容易获取和使用。
React和Vue的共性:
使用虚拟DOM。
提供响应式视图组件。
专注于开发过程中的一个方面。目前集中在视图层。
有这么多相似之处,你可以假设它们都是同一事物的不同版本。
这两个库之间有一个主要的区别:它们如何让开发人员创建视图组件,反过来又可以应用程序。
React采用JSX(这个词是react团队创造的)渲染内容到DOM。那么什么是JSX?基本上,JSX是一个JavaScript渲染功能,帮助你将你的HTML放到你的JavaScript代码中合适的地方。
Vue采用不同的方法,使用HTML模板。使用Vue模板就像是用JSX就是他们都是创建使用JavaScript。主要的区别是,JSX函数在实际的HTML文件中从来不被使用,而Vue模板不是这样。
特别说明下,Vue.js的相关课程可以点击这里。
React JSX
我们将深入探讨JSX如何工作。假设你有一个要在DOM上显示的名称列表。你们公司最近的一份新员工名单。
如果你使用的是普通的HTML,你首先需要创建一个index.html文件。然后,你将添加以下代码行。
<ul>
<li> John </li>
<li> Sarah </li>
<li> Kevin </li>
<li> Alice </li>
<ul>
</pre>
这里没什么好说的,只是普通的HTML代码。
那么你使用JSX怎么做同样的事情?第一步是创建一个index.html文件。但是,不像以前那样添加完整的HTML,只需要添加一个简单的div元素。这个div将是容器元素,在那里您的所有React代码将被呈现。
div将需要一个唯一的ID,这样React就知道如何可以找到它。facebook倾向于支持根关键字,所以让我们坚持这一点。
<div id=root></div>
现在,走到最重要的一步。创建包含所有react代码的JavaScript文件。这是一个叫app.js的文件。
你现在把所有的事情都排除在外,进入主事件。用JSX显示所有新员工到 DOM中。
首先需要创建一个具有新雇员名称的数组。
const names = [‘John’, ‘Sarah’, ‘Kevin’, ‘Alice’];
从那里,您需要创建一个响应元素,它将动态地呈现整个名称列表。这你没有必要再手动显示每一个。
<ul>
{names.map(name => <li>{name}</li> )}
</ul>
);
这里要注意的关键是,您不必创建单独的**<li>元素。你只需要描述你想让他们看一次,React会处理剩下的。这是一件非常给力的事。虽然你只有几个名字,但想象一下有成百上千的名单!你可以看到这当然是一个更好的方法。特别是如果<li>**元素,比这里用到的元素更复杂。
代码的最后一步是需要将内容渲染到屏幕,主要是通过ReactDom的render渲染函数。
ReactDOM.render(
displayNewHires,
document.getElementById(‘root’)
);
在这里,你在用div里的内容作出响应,通过displayNewHires渲染root元素。
那么最终的React代码就应该是这个样子:
const names = [‘John’, ‘Sarah’, ‘Kevin’, ‘Alice’];
const displayNewHires = (
<ul>
{names.map(name => <li>{name}</li> )}
</ul>
);
ReactDOM.render(
displayNewHires,
document.getElementById(‘root’)
);
这里要记住的一个关键是,这是所有的React代码。这意味着它都将编译成普通的JavaScript。下面是它最终看起来的样子:
‘use strict’;
var names = [‘John’, ‘Sarah’, ‘Kevin’, ‘Alice’];
var displayNewHires = React.createElement(
‘ul’,
null,
names.map(function (name) {
return React.createElement(
‘li’,
null,
name
);
})
);
ReactDOM.render(displayNewHires, document.getElementById(‘root’));
这就是它的全部。现在有一个简单的React应用程序,它将显示名称列表。没有什么可以写的,但它应该能让你了解React的能力是什么。
特别说明下,react.js的相关课程可以点击这里。
Vue.js Templates(模板)
按照最后一个示例,您将再次创建一个简单的应用程序,它将在浏览器上显示名称列表。
你需要做的第一件事就是创建一个空的index.html文件。在该文件中,您将创建一个带有根ID的空div。记住,根只是个人偏好。你可以调用你的ID无论什么情况下。您只需确保稍后将HTML与JavaScript代码同步时匹配起来即可。
这个div会像它在React中那样起作用。它会告诉JavaScript库,在这个示例中,开始改变的时候在哪里观察DOM。
一旦这样做了,你将创建一个JavaScript文件,将存放Vue代码。称它为app.js,以便保持一致。
现在你已经准备好你的文件,让我们看看Vue如何显示元素到浏览器。
Vue使用模板的方法用它来操作DOM。这意味着你的HTML文件不仅会有一个空的div,比如在React中。实际上,您将在HTML文件中编写一部分代码。
为了给你一个更好的提醒,回想一下使用普通HTML创建名称列表需要什么。一个**<ul>包含一些的<li>**元素。在Vue,你要做几乎相同的事情,只有少数的变化增加。
创建一个**<ul>**。
<ul>
</ul>
现在添加一个空的**<li>**。
<ul>
<li>
</li>
</ul>
没什么新鲜的变化,通过增加一个指令,一个自定义的Vue的属性你的**<li>**元素。
<ul>
<li v-for=’name in listOfNames’>
</li>
</ul>
指令是Vue直接进入HTML添加JavaScript功能的方式。它们都以V开头,后面跟着描述性的名字,让你知道他们在做什么。在这个实例中,它是for循环。每一个名字在你的名字列表listOfNames中,你可以从你的名单列表上复制这个<li>元素和更换一个新的<li>元素来确定一个的名字。
现在,代码只需要最后一次编写。当前,它将为列表中的显示每个名称,但实际上并没有告诉它将把实际名称显示在浏览器上。为了解决这个问题,你将在你的<li>中插入一些类似mustache的语法。你可能在其他JavaScript库中看到的类似东西。
<ul>
<li v-for=’name in listOfNames’>
{{name}}
</li>
</ul>
现在<li> 元素是写完了。它现在将显示名字为listOfNames列表的每个项。记住name可以是任何其他的名称。你可以把它叫做item,它也会达到同样的目的。所有关键字都用作占位符,用于在列表中迭代。
你需要做的最后一件事就是创建数据集和在实际应用程序中初始化Vue。
这样做,你将需要创建一个新的Vue实例。通过将它分配给名为app的变量来实例化它。
let app = new Vue({
});
现在,对象将包含一些参数。第一个是最重要的,el (element) 参数告诉Vue在DOM开始添加什么内容。就像你对你的React中的例子那样。
let app = new Vue({
el:’#root’,
});
最后一步是添加数据到Vue的应用。在Vue,所有的数据都将做为Vue实例的参数传送到应用程序。另外,每个Vue实例只能有一个每种类型参数。虽然有相当多的,但您只需要集中在两个例子,el和data。
let app = new Vue({
el:’#root’,
data: {
listOfNames: [‘Kevin’, ‘John’, ‘Sarah’, ‘Alice’]
}
});
数据对象将接受一个数组listOfNames。现在,每当您想在应用程序中使用该数据集时,只需要使用指令调用它。很简单,对吧?
这是最终的代码:
HTML
<div id=”root”>
<ul>
<li v-for=’name in listOfNames’>
{{name}}
</li>
</ul>
</div>
JavaScript
new Vue({
el:”#root”,
data: {
listOfNames: [‘Kevin’, ‘John’, ‘Sarah’, ‘Alice’]
}
});
结论
现在你知道如何使用React和Vue创建两个简单的应用程序。他们都提供了强大的功能,虽然Vue看起来往往是更容易使用。还有需要记住,Vue也支持JSX的使用,虽然它不是首选的实现方法。
无论哪种方式,Vue和React都是两个功能强大的库,你使用任何一个都不会有问题。
如果你觉得这篇文章很有帮助,给我一些掌声。
你可以在Twitter上跟踪我!
汇智网(www.hubwiz.com,有很多很棒vue.js的课程包括vue.js\vuex\vue-router\vue工程化等)的小智原创翻译。
[北京]区块链创业公司,行业大牛+顶级团队
大家好,我们是在北京的一家区块链创业公司,现在也在开西雅图的办公室,所以目前北京西雅图都可以。具体做什么可以私下沟通,但绝对算是目前国内区块链创业团队里面中上甚至是顶级的机会。 公司的合伙人在圈内有一定影响力,员工也有不少是从硅谷,新加坡等地过来的,整体的团队还是很不错的。 如果你想真正学习区块链技术,抢先踏上下一个互联网的浪潮,现在行动肯定没错。 待遇方面不用担心~ 职位:
- 后端开发工程师
- 后端服务用的是python django,有其他经验的能快速上手也可以
- 最好对区块链技术有了解以及有兴趣
- 良好的代码习惯,适应code review,适应阅读英文文档
- 测试工程师 (急)
- 有移动端产品的测试经历,最好了解区块链行业或做过区块链项目
- 对主流的测试工具,版本控制工具有经验
- 前端 / React Native开发工程师
- 较为扎实的JavaScript代码能力,熟悉ES6+标准
- 有主流前端框架的使用经验,React、React Native为佳,其他框架能够快速上手也可以
- 良好的代码习惯,可以适应Code Review的流程,能良好的阅读英文文档
- 加分项:了解区块链相关技术或有强烈兴趣,了解数据可视化或者WebGL,了解RxJS,有IOS或者安卓APP开发经验
- DevOps / 运维工程师
其他值得你关注的地方:
- 良好的Codebase,大牛很多,在做东西的同时是锻炼技术的好机会
- 15寸顶配MBP + 34曲面屏显示器,能有的都会提供
- 最重要的还是机会真心不错,团队里很多人都是从上海,新加坡,甚至美国搬过来的,和一般大型互联网公司的机会是两个概念
- 举例Team成员待过的公司:Google, Facebook, Twitter, OKCoin, 高盛,以及能吸引到这么多人的CEO…
欢迎自荐或者推荐,邮箱liukai9293@qq.com,微信liukai730219
如何正确的使用Ant Design Pro?
《提问的智慧》已经看完。 好了,开始提问:写JAVA-SSM框架的全栈程序员(大家给点面子就当我是好了)如何使用Ant Design Pro?
Ant Design Pro我看了说明:Ant Design Pro 是一套基于 React 技术栈的单页面应用,我们提供的是前端代码和本地模拟数据的开发模式, 通过 Restful API 的形式和任何技术栈的服务端应用一起工作,那他的意思就是只有一个html页面切换全靠#,#表示我以前只是拿来定位现在还要我路由,压力很大。而数据还需要靠另一个服务器提供。难道这就是前后台分离。。。Pro使用的是React将html和js捆绑在一起变成组件。那我还怎么安静的写html和jq呀。。我还想$("#id").val()也不行了吗?
如果我运用了React的思想组件化,那我是不是就不能把Ant Design Pro定位成前端框架了,而要把它想成一套解决方案?最后一点就是我想用Ant Design Pro到自己的项目中。但是我没搞懂Ant Design Pro的定位。。。如果对比Ant Design Pro和express框架?
以上问题让我处在混沌之中,不求甚解
还在为项目文档烦恼嘛,DOClever让你的项目文档纵享丝滑
现如今,很多互联网团队对于开发效率的要求越来越高,市面上也有越来越多的工具来辅助我们完成团队协作,但是很多工具都比较偏向重量级别,且闭源收费,那么今天,我想为各位介绍一款开源免费且功能强大,支持线下部署,融合了文档和接口管理的轻量级协作工具DOClever
首先我们可以在线上环境先体验下,如果觉得不错,可以部署线下的环境(GitHub:sx1989827/DOClever),我们打开DOClever的官网:http://doclever.cn注册一个新账号,然后登陆到控制台,在项目中选择切换到文档标签页,新建一个项目: 点击项目,进入项目首页: 这里我们可以看到已用空间和总空间,如果是线上环境,最大空间默认是10m,如果是线下部署环境就没有空间大小的限制。我们点击编辑按钮,进入全屏编辑页。 编辑区域采用的是markdown语法编写,因为用的是websocket,所以彻底告别手动保存,实时修改实时保存,同时支持实时滚动预览,我们在内容编辑区点击右键,弹出操作菜单: 点击上传图片或者上传附件,便可以将本地的图片或者附件直接推到上传框,完成上传后即可实时显示: 同时,编辑区域也支持粘贴图片,如果你有截图或者网页上复制了图片,那么在你需要插入的位置按下粘贴的快捷键即可上传图片!
因为DOClever一直在做接口管理的功能,所以对于接口的支持是非常强大的,它可以实现接口和文档的无缝连接,我们在刚才的右键菜单选择插入接口,我们便可以选择不同的团队,不同的项目,不同的版本的接口了: 允许运行的滑块是运行用户测试该接口的内容数据: OK!我们点击保存,在预览区域便可以看见我们的接口链接了,点击该链接,便会出现接口的详情页。 我们点击弹出框最下面的运行按钮,便可以测试该接口的数据了。 以上便是文档的编辑功能,当然了,文档还支持在线分享和导出成pdf,可谓是十分的方便快捷!
不仅如此,DOClever项目文档的强大之处在可以和接口很好的融合,我们通过快速切换栏切换到我们刚才插入的那个接口所在的接口项目下。 点击上图的所示的图标按钮,便可以显示在哪些文档中的引用了该接口。 点击文档,滚动条便会自动滑到接口被引用的位置! 好了,以上就是关于DOClever的项目文档功能,在接口管理的加持下,为您的开发效率如虎添翼!
DOClever,让接口驱动生活!
微信跳一跳辅助工具(基于Node.js)
这是一个需要手动来玩的辅脚本,也是最为保险,官方无法禁封的辅助工具;
支持Mac OS
、windows
、Linux
系统,无需要手动设置adb
环境。
视频演示:http://v.youku.com/v_show/id_XMzI5MDY3Njk0MA==.html?spm=a2hzp.8253869.0.0
安装
本地环境只需要安装好Node.js 7.6
以上的版本即可(推荐8.9.3
);
国内网络环境建议安装好cnpm
:
# cnpm安装
npm install -g cnpm --registry=https://registry.npm.taobao.org
使用
- Android手机打开USB调试(一般操作步骤:设置–>开发人员工具–>打开USB调试)
- 连接手机到电脑,并在弹出的询问窗口中点击信任设备
clone
或下载项目文件到本地并解压- 使用
bash
或cmd
进入到解压好的目录 cnpm install
或npm install
安装相关依赖node index.js
运行即可- 打开《跳一跳》游戏并点击开始
- 浏览器访问
http://localhost:5200
- 不出意外,此时电脑上会显示手机截图,在画面区域用鼠标连接两个方块的中心点,然后点击右侧的【GO】按钮。手机上跳完之后,新的截图会同步到浏览器中,手动重复该步骤即可
提示:
- 各手机型号分辩率不一样,可根据自身设备在右侧的
Time/px
输入框中微调设置合适的值,直到每次能能跳到最中心; - 连接两点之间,建议找好对应的参考点,例如:
小人的菊花
-->目标中心
,见下图所示。
原理
使用Node.js
调用adb
命令,拉取手机截图到浏览器。
用户在浏览器手动完成两个点的标记之后,点击【GO】按钮,通过socket
消息告诉Node
去执行adb
操作。
之后将新的画面传回到前台…
PS
目前现成其它方案:
- 拦截数据包伪造数据请求的 (修改数据提交加密方式就可被封掉)
- 自动识别画面完成跳跃的 (画面添加不规则的图案或干扰画面,自动识别即可能较难做到)
Node.js会因为Meltdown就此衰落吗?
如题
Koa 模板引擎 性能最好的是?
ejs WRK了几次,性能欠佳,想找个QPS高的,求各位神仙支持
Running 1m test @ http://127.0.0.1:8080 4 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 32.42ms 41.41ms 1.24s 99.32% Req/Sec 842.77 110.65 1.09k 74.06% 201431 requests in 1.00m, 153.33MB read Requests/sec: 3351.72 Transfer/sec: 2.55MB
关于eggjs,有些疑惑
今天学习了下eggjs,
- 现在的mvc存在的场景是什么
- 企业级的框架和应用是什么
superagent上传stream时上传内容不全,只上传了一个highWaterMark 大小,哪里问题呢
使用superagent 上传大文件时,例如10M,结果只上传了64k, code:
const request = require('superagent');
const path = require('path');
const fs = require('fs');
const hostUrl = 'http://localhost:3000';
const filePath = path.resolve(__dirname, './data/test-big.json');
const readStream = fs.createReadStream(filePath);
let streamRequest = request.put(hostUrl + '/upload');
readStream.pipe(streamRequest);
觉得流在上传了一个highWaterMark 后就终止了,求助
[杭州滨江]阿里巴巴-CBU技术部招聘全栈高级工程师/专家
CBU技术部介绍: 中国消费升级的历史机遇下,企业服务是最近10年的风口,阿里新零售、新制造等五新战略下CBU技术团队正在打造中小企业端的批发市场,采购SaaS工作平台和分销工具平台。 团队以年青,激情,快乐为特色工程师文化,目标成为一支懂商业的工程师团队。工作中将有机会面对复杂的商业场景对于技术扩展商业的能力的挑战,大数据、高并发、云计算、IOT、AI和无线等新技术应用场景。我们的使命是用新技术赋能中小企业,帮助其在新消费时代完成供给侧变革;我们的愿景是成为阿里集团内最懂中小企业的技术团队。
职位描述 参与项目的系统分析、设计,负责核心功能与底层基础功能的功能设计及开发; 参与建设通用、灵活、智能的业务支撑平台的讨论与设计,支撑上层多场景的复杂业务。
职位要求 计算机软件或相关专业,3年以上NodeJS开发经验; 熟练掌握NodeJS基础技术体系(包括常用基础模块、异步机制、IO、网络)以及流行框架; 有运用nodejs开发大型系统的经验; 良好的编码习惯,熟练掌握测试用例的编写; 具有比较强的问题分析和处理能力,有比较优秀的动手能力,热衷技术,精益求精,有一定的技术癖; 熟悉业界流行的前端技术体系,必要时能投入一定前端开发;
职位地点:杭州滨江区
PS:1月27号有北京招聘专场,,来专场与技术大牛面对面交流,获得极速面试反馈,我们在北京等你。
简历投递地址: yuefei.myf@alibaba-inc.com
热烈欢迎感兴趣的同学积极投递简历,万分感谢中期待与你共创新零售的未来
分享我自己用Koa2+Vue2写的一个博客管理系统Ashen Blog
先展示一下
最初想做这个Blog,主要是看到了一位厉害的学长Chuck Liu的作品:
非常感谢的是Chuck Liu学长开源的系统,我在开发的过程中从他的代码里学到了很多知识,从架构到开发的都有,在写客户端的代码时,因为对自己的设计感实在绝望,也沿用了学长的布局,非常感谢。
另外令人开心的是,写这样一个系统也帮助学长de了一个小bug,也算是Kov-Blog的contributer了吧!
先放上demo和截图~~~ demo
客户端界面
管理端界面
介绍
Ashen Blog系统遵循ES6+的代码标准,前端采用了Vue 2.x作为开发框架,后端采用了Koa 2.x作为RESTful API 服务器开发框架,是一款前后端分离并利用axios进行数据通信的单页面应用。
Client端展示博客,目前有:文章列表、文章详情、日期归档、标签归档、阅读列表和个人介绍。
Admin端管理博客,目前支持:Markdown编写博客、快捷按键及Tool bars、自动保存博客、批量标签管理、阅读列表管理、撰写个人介绍。
Server端作为RESTful API服务器,负责与Client/Admin端进行数据通信。
数据持久化方面使用Mysql作为数据库。
最后
详细的文档在我的github上:
由于水平还不怎么样,所以代码肯定存在很多问题,希望大家多提issue和pr,非常感谢~~~
另外走过路过不要忘记留下star啊~~~
二鞠躬~~~
分享一个使用Egg.js和semantic-ui-react开发的article小demo。
预览效果 客户端地址:https://github.com/five6/jyg_client api地址:https://github.com/five6/jyg_server
mongoose 连接问题
function connect_mongo(db){
console.log('HOSt',MONGO_HOST)
if( MONGO_USER != '' && MONGO_PASSWORD != ''){
var dburl = 'mongodb://'+ MONGO_USER + ":" + MONGO_PASSWORD +'@'+ MONGO_HOST+":"+MONGO_PORT+'/'+db
} else {
var dburl = 'mongodb://'+ MONGO_HOST +':'+MONGO_PORT+'/'+ db
}
console.log('dburl',dburl)
dbConnection = mongoose.createConnection(
dburl,{
config: {
autoIndex: false //不自动创建索引
},
server: {
auto_reconnect: true //自动重连
}
}
)
dbConnection.on('open',()=>{
console.log(db+'连接成功')
})
dbConnection.on('error',()=>{
console.log(db+'连接失败')
})
dbConnection.on('close',()=>{
console.log(db+'连接关闭')
})
return dbConnection;
}
使用一个函数去进行数据的连接,但是为什么我明明填下去的mongodbhost是192.168.0.253,log打出来也是
// This is log
2018-01-04 20:20 +08:00: HOSt 192.168.0.253
2018-01-04 20:20 +08:00: dburl mongodb://192.168.0.253:27017/argus-web
2018-01-04 20:20 +08:00: HOSt 192.168.0.253
2018-01-04 20:20 +08:00: dburl mongodb://192.168.0.253:27017/argus-statistics
2018-01-04 20:20 +08:00: HOSt 192.168.0.253
2018-01-04 20:20 +08:00: dburl mongodb://192.168.0.253:27017/argus-alert
2018-01-04 20:20 +08:00: HOSt 192.168.0.253
2018-01-04 20:20 +08:00: dburl mongodb://192.168.0.253:27017/argus-users
2018-01-04 20:20 +08:00: argus-statistics连接成功
2018-01-04 20:20 +08:00: argus-web连接成功
2018-01-04 20:20 +08:00: argus-alert连接成功
2018-01-04 20:20 +08:00: argus-users连接成功
但是之后就会报连接错误,错误的是地址错了
MongoError: failed to connect to server [2.168.0.253:27017] on first connect [MongoError: connect ETIMEDOUT 2.168.0.253:27017]
at Pool.<anonymous> (F:\git\argus-web\server\node_modules\mongodb-core\lib\topologies\server.js:336:35)
at emitOne (events.js:116:13)
at Pool.emit (events.js:211:7)
at Connection.<anonymous> (F:\git\argus-web\server\node_modules\mongodb-core\lib\connection\pool.js:280:12)
at Object.onceWrapper (events.js:317:30)
at emitTwo (events.js:126:13)
at Connection.emit (events.js:214:7)
at Socket.<anonymous> (F:\git\argus-web\server\node_modules\mongodb-core\lib\connection\connection.js:187:49)
at Object.onceWrapper (events.js:315:30)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickDomainCallback (internal/process/next_tick.js:218:9)
有大神们知道是什么原因吗?
初学Node心中一直存在这么一个疑问?
比如说,在一个html页面中有一个可以点击并且可以触发一个事件的按钮,点击这个按钮会执行一个函数(返回当前html文件所在的项目文件路径)。我的问题是:Node应该如何监听这个事件,或者说,Node是如何知道用户在页面点击了什么按钮,执行了什么事件?刚刚接触后端,总感觉这个问题很愚蠢,但确实想不通???请赐教!
Node.js Middleware
Express.js is a very lightweight and minimalist web framework for Node.js with routing and middleware functionality at its core concept. Basically, an Express application is a series of middleware function calls. Middlewares is such an important concept in Express.js that once you understand it clearly, you will be able to create a more robust and maintainable application. To read more, click Optimize Middleware implementation in Express application - part 3here
请问c扩展 c 外部函数接口 和 c 混写有什么区别?
请问c扩展 c 外部函数接口 和 c 混写有什么区别? 主要是调用方式和速度 谢谢
分享一个React源码解析
中文版: 知乎专栏英文版: HACKERNOON (on Medium)原文: 博客