Headless Chrome: an answer to server-side rendering JS sites

原文:https://developers.google.com/web/tools/puppeteer/articles/ssr#inline TL;DR: 无头模式的 Chrome(Headless Chrome) 可以成为将动态 JS 站点转化成为静态 HTML 页面的入门工具。在 Web 服务器上运行它能够让你预渲染任何具备任何现代 JS 特性的页面,使得页面内容加载更快而且可以被爬虫工具索引到。 这篇文章的技术方案为大家展示了如何使用 Puppeteer 的 API 来为一个 Express web 服务器添加服务端渲染(SSR)的功能。其中最棒的一点是 Express app 本身几乎不需要做代码修改。繁重的任务将交给 Headless Chrome。你只需要添加短短几行代码你就可以 SSR 任何一个页面,并且得到该页面的最终完整 HTML…

JavaScript 中的 HTTP 跨域请求

自从我接触前端以来,接手的项目里面很大部分都是前后端分离的,后端只提供接口,前端根据后端接口渲染出实际页面。个人觉得这是一个挺好的模式,前后端各自负责各自的模块,分工明确,而且也给前端更大的发挥空间。 与以前套模板的模式不同,前后端分离以后,前端跟后端的沟通绝大部分都是通过前端主动向后端发起请求来完成的。而前端的请求又绝大部分是由 Ajax 构成的,Ajax 是一种非常方便的获取数据的方式。但是,一旦 Ajax 碰上跨域,那么问题就会麻烦很多。这篇文章主要梳理了我在项目开发里面碰到的一些关于跨域请求的问题,当然也会有一些关于跨域请求的一些背景知识。PS:文末有个小彩蛋哦😄 严格来说,跨域请求并不仅仅只是 Ajax 的跨域请求,而是对于一个页面来说,只要它请求了其他域名的资源了,那么这个过程就属于跨域请求了。比如,一个带有其他域名的 src 的 <img> 标签,以及页面中引入的其他第三方的 CSS 样式等。 对于 img 以及 CSS 而言,跨域请求本身并没有更多的安全问题,因为这些请求都属于只读请求,…

记一次网件 R6300V2 路由器救砖经历

今年三月在张大妈的诱惑之下,我终于剁手了传说中的电磁炉——网件 R6300V2 路由器,开始了我的路由器折腾之路。其实一开始我的想法是想买一个可以刷 OpenWRT 固件的路由器,然后在路由器运行 Shadowsocks ,实现网络的自动代理功能。其实满足这个需求的路由器实在是太多了,一百来块的路由器就能实现这个目的。但是在张大妈逛得越久心里就越不踏实,想着要不一步到位,干脆买个双频的,性能强悍一些的,顺便还能够挂载移动硬盘的,当个迷你 NAS ,想想都觉得很美好。于是乎,R6300V2 就成了不二之选。 买回来以后到现在,陆陆续续刷了好几个固件,一开始是 koolshare.cn 上的梅林固件,然后是 DD-WRT ,然后是 Tomato 。但是,由于在刷 Tomato 的时候忘记恢复出厂设置了,导致刷完之后路由器变砖了,电脑连上去之后分配不到 IP ,无法 ping 通 192.168.1.1 ,所以也就有了这次救砖经历。…

个性化定制 Sublime Text 3

说起来也挺惊讶的,自己在前端这条路上已经走了三年多了。三年多的时间积累,让我这个『自学成柴』的小伙子多多少少也有了一些经验。经验告诉我,一个顺手高效的编辑器能够让你的开发效率得到很大的提高。印象中我从一开始就一直使用 Sublime Text 3 作为我的编辑器,期间从未改变过。 当然这并不是说我没有尝试过其他编辑器或者 IDE ,事实是我试过 Brackets,Atom, VS Code, 以及 JetBrains 的 Webstorm ,这几款编辑器/IDE 都挺优秀的。但是感觉都不太适合我。我还是钟爱 Sublime Text 多一些。大概是因为 Sublime Text 实在是太快了,以及,多多少少有一点==先入为主==的心理作用吧。 然而 Sublime Text 也并不是开箱即用的编辑器,它需要安装一些额外的插件以及经过一系列的配置,才能够做到更加顺手和美观。自己用了这么久的 Sublime Text…

Ghost Theme demonstration - decent

这是我自己写的一个 Ghost 博客主题的演示文章,用来展示文章页的样式。 文章内的图片来自 Unsplash 和 Death to Stock Photography,文字内容来自 Lipsum] The standard Lorem Ipsum passage, used since the 1500s Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco…

CSS3 中的 Flexbox 详解

什么是 Flexbox ? Flexbox 是指 CSS 中将元素的 display 规则设置为 flex 或者 inline-flex 时所展示出来的布局模式。 主要为了解决什么问题? 高效灵活地布局,对齐。 在 Flexbox 尚未出现之前,页面的布局通常都是用浮动或者绝对定位和相对定位来实现。布局方式不多,但是也勉强可用。但是到后来,随着前端技术的快速发展以及页面布局需求的快速迭代,传统的布局方式在越来越酷炫和高大上的设计稿前面,就显得表现力不足以及布局变得麻烦而且不够灵活。特别是对于元素的对齐,往往得花费一定的精力使用各种技巧才能实现。Flexbox 这一布局方式的出现则可以看做是为了解决布局和对齐这个问题的一种尝试。 解决移动端上页面布局的难题。 如今的智能设备越来越多,设备的尺寸也越来越多。很明显,开发者不可能为每一种屏幕尺寸提供一套解决方案,只能说提供一套通用的解决方案来适配各种各样的设备。再者,现在的智能设备大多都支持屏幕旋转功能。而屏幕旋转功能则会在一定程度上影响到页面的布局。这个问题也是传统布局方式所无能为力的,或者说,目前为止仍然没有一种非常优雅地解决方案来解决这个问题,直到 Flexbox 的出现。 Flexbox 使用方法 .flexbox-parent { border: 1px solid…

JavaScript 数组去重

故事的起因来自牛客网的一个测试,里面有一道数组去重的题,题目如下: 为 Array 对象添加一个去除重复项的方法 输入例子: [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN].uniq() 输出例子: [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a'] 之前刚好碰到过数组的去重这个问题,于是按照之前的印象,想都没想就写下: Array.prototype.uniq = function () { var map = {}; return this.filter(function (item) { if (map[item]) { return false; } else { map[item] = true;…

== VS === ? The Evil or the Angel ?

如果你是一个前端开发人员的话,那么难免会遇上这样的情况: console.log(0 == false); // true console.log('' == false); // true console.log([] == false); // true console.log(0 === false); //false console.log('' === false); //false console.log([] === false); // false 不熟悉 JavaScript 的开发者也许会问:== 为啥既然有了 == 了,还要 === 干啥?这两者有什么区别?== == 顾名思义,是相等运算符。而 === 是全等,也叫严格模式下的相等。上面的例子其实可以看出这两者有挺大的区别的。 在 JavaScript 中,== 运算符会在进行比较的时候进行一次隐式类型转换,这个转换是开发人员看不到的。比较的结果也会像前面的例子那样神奇。…

JavaScript Promises 初探

在 Promise 产生之前的 JavaScript 一说起 JavaScript,给人印象最深的,应该是活在浏览器里面的各种各样的脚本了。但是如今 Node.js 发展非常迅速,npm 社区也非常活跃,因此也越来越多人关注后端的 JavaScript 。 不得不说,在 JavaScript 里面,事件绑定以及事件处理是一个非常重要的部分。 前端部分,诸如鼠标点击事件的绑定,以及键盘按键的绑定,以及和后台打交道的 Ajax 等,都使用到了事件机制。 最简单的一个点击事件如下: var target = document.getElementById('target'); target.addEventListener('click', function () { // handle click event }); 以上我们监听了一个 ID 名为 target 的HTML元素,并赋予了一个匿名函数。当我们点击它时,则触发点击事件,然后执行相应的函数。…