很多教程把Promise搞的过于简单或复杂,这里梳理下,强化下个人理解。

Promise产生的原因

promise是异步编程范畴内为了解决回调地狱的产物。

1
A.then(B).then(C)
阅读全文 »

IDEA作为code开发主力,但是更适合完整项目开发,而VSC作为轻量级开发编辑器,比如有时候处理一个Nginx配置,一个HTML测试文件等,因此两者不矛盾,一个重型武器,一个轻量级冲锋枪。

将VSC打造成一款利器更需要点成本,因为本身并不自带很多功能,因此需要安装相对较多的插件,这里列举下我安装的几款插件。

持续更新调整

  1. Auto Rename Tag

    自动重命名配对标签

  2. browserslist

    配置高亮

  3. code-groovy

    groovy语法支持,偶尔进行Jenkins pipeline配置,因此需要

  4. Darcula IntelliJ Theme

    IDEA主题,这样可以确保与IDEA有一样的代码风格

  5. EditorConfig for VS Code

    EditorConfig配置支持,确定文件基本编码,格式

  6. HTML CSS Support

    id,class属性提示

  7. HTML Snippets

    HTML常用代码片段

  8. IntelliJ IDEA Keybindings

    最大程度的保持与IDEA一块的快捷键

  9. JavaScript (ES6) code snippets

    高亮输入JS代码片段

  10. NGINX Configuration

    conf文件语法高亮

  11. open in browser

    浏览器中打开

  12. PlantUML

    UML绘制

  13. WakaTime

    编程活动追踪

  14. Python

    py语法支持

注意,推荐绑定GitHub进行设定多设备同步/备份

阅读全文 »

这三个词汇频繁出现在前端安全范畴,这里总结下。当然由这三个词汇还会串联出相关一些知识点,比如同站,跨域,XSS,CSRF等。

这些术语看着复杂多样,但是联系起来考虑他们实际的场景就很好理解了。

  • 同源安全策略的出现

    • 同源即协议,域名,端口均一致即是同源,不同源情况下发起异步请求即产生跨域,浏览器在保证安全起见,对于XHR,这类异步请求进行了同源安全策略限制。假如说没有同源的限制,那么A网站完全可以直接请求B网站的资源,A在未知情况下请求了流氓站点B的资源,B获得了A的数据,操作DOM等等,总之并不安全,因此同源限制是有必要的。但也需要知道,比如HTML中的Script,Img是没有同源限制的。
    • 还是同样资源,如果是XHR发起的Script资源获取等,CSS中发起的font加载即会受到跨域限制。
  • 同源虽好但是依然有缺陷,比如页面本身被注入了一些恶意脚本然后执行造成了XSS攻击,那么还是会破坏网站安全,这又如何保证呢,那么CSP就有作用了,CSP通过明确资源来源,资源类型等方式进一步确定了网站中资源的安全,比如CSP如果明确了只能是外链JS,那么即使注入了页内JS也会报错不执行。

  • 如上同源安全策略+CSP就一定程度的保障了站点的安全,但是安全的同时也让灵活性得到了削弱,比如A站点如果确实就想访问B站点的资源,并且AB本身彼此很确定安全呢,那么CORS就来了,CORS确定了服务方明确了授权的被服务方,这样就可以达到资源复用的灵活。

    • 面对同源限制,一种办法是CORS,一种是反向代理,因为后台服务是没有同源限制的,比如前端开发时,有时候请求的后端并不是本地,所以地址一定不同,会触发跨域,因此我们一般是配置了代理解决。
  • 如一开始所说同源还是很严格的,但是比如一个企业它的网站有很多,比如a.111.com与b.111.com它们不同源,但是它们有时也需要一定程度的复用一些资源,如何做,同站的概念就出现了,同站只要求顶级域名一致即可。如果是同站,比如A站点中点击链接打开了B站点,因为同站,且具有同一个执行上下文,那么AB会复用同一个渲染进程,B站点下通过windw.opener是可以操作A站点窗口的。

  • 有提到HTML中的Script,Img是没有同源限制的,那么有时资源会被盗用,又如何确保这些资源的安全呢,refer防盗链就出现了,HTTP请求时,请求头部会有refer资源,服务端根据refer可以进行403防盗处理。那如果refer可以被篡改,不就照样可以盗用资源了?因此,refer在浏览器端是不可以被篡改的。

写在最后

串起来这些之后可以明白这些技术是逐步发展,逐步在安全与便利性中取得得平衡。理解了就不难了。

阅读全文 »

最近项目并不紧张了,于是得空把一些基础理论梳理下

  1. 当用户URL输入一个网址,浏览器根据用户输入的信息判断是关键词还是网址,如果是关键词则利用默认搜索引擎拼接输入的关键词形成网址,如果输入即是有效网址,则加上协议形成URL,用户输入完内容,按下回车
  2. 回车前,如果当前有页面存在则,执行beforeunload方法
  3. 浏览器导航栏显示loading
  4. 浏览器进程构建请求行信息,以IPC方式将请求行信息发送给网络进程
  5. 网络进程接收到该URL请求
  6. 网络进程中查询该URL资源是否有缓存(强缓存),如果有则相当于请求结束拿到响应数据,直接返回200响应头给浏览器进程,如果没有,则继续发起网络请求
  7. 网络进程中查询DNS确定URL对应的真正IP地址,如果是HTTPS,建立TLS连接
  8. 通过IP地址和端口与目标服务器建立TCP连接【TCP连接三次握手】,成功后开始构建请求头(附带Cookie),向服务器发送HTTP请求【单个域名TCP连接数量限制,比如Chrome是6】
  9. 服务器获得信息后,会构建响应信息,发送给网络进程
  10. 网络进程获得响应信息,解析响应行的状态码来确定下一步的动作,如果是301,302则获取location,然后重复执行接收到一个URL之后的一系列动作,如果是304说明客户端有缓存,则返回304头部到浏览器进程,如果是200则继续
  11. 根据响应头的内容类型来确定下一步的动作,如果是下载类型,则唤起浏览器下载器进行下载,如果是HTML则继续
  12. 渲染进程存在打开新进程的情况,如果是新开的页面,开启新的渲染进程,如果是A页面打开的B页面,同站点,且没有开启noopener则复用A的渲染进程
  13. 浏览器进程接收网络进程的响应头数据,向渲染进程发送【提交文档】信息,渲染进程接收到【提交文档】信息后,与网络进程建立传输数据管道
  14. 渲染进程接收完毕,向浏览器进程发送【确认提交】
  15. 浏览器进程接收【确认提交】信息后,进行安全栏,前进后退界面更新
  16. 渲染进程:DOM生成=>样式计算=>布局=>分层=>图层绘制=>分块=>光栅化=>合成绘制
  17. 渲染进程渲染完成后,向浏览器进程提交页面加载完毕

参考资料

阅读全文 »

作为前端developer总是要经常查看networks,HTTP请求不可避免要接触,但一直缺乏系统的学习,于是查询这里梳理下,加深下记忆。

HTTP定义

超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议HTTP是万维网的数据通信的基础。HTTP协议是1989年发起的,当前标准由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调发布。

需要知道

  1. HTTP是个已有30多年的历史的协议
  2. HTTP通常建立在TCP/IP协议之上,但HTTP协议中并没有规定它必须使用或支持的层。因此HTTP可以在任何互联网协议或其它网络上实现
  3. HTTP请求的发起端不一定是在浏览器,爬虫或者其他工具均可
阅读全文 »

Chrome DevTools下调试前端请求时,会注意到缓存分为两种MemoryCache,DiskCache,针对两者区别和Chrome是如何选择缓存介质的,这里基于我的认知总结下。

概念

单说区别,简单,仅从名字上也可以看出两者的区别,MemoryCache是从内存中存取,因此速度快,但时生命周期短,而DiskCache是磁盘存取,因此读写较慢,但生命周期相对较长,属于持久化存取。

缓存介质选择

对于两种缓存介质的选择,官方权威资料并没有找到,于是我只能做了下测试,同时得出以下的结论。

阅读全文 »

身为前端er,在过去的几年经常使用这两个函数但是真的傻傻分不清,总是需要使用使用看API,或者TS定义,还是抵消,最好的办法还是脑子里彻底记住,毕竟漫威英雄啥的咱不是记得都门儿清吗。so,还是功夫用的不够。

这里就mark下两者的区别,用于记忆。

splice

单词含义

绞接,捻接

阅读全文 »

最近Stackoverflow上看到一个问题,Are ES6 template literals faster than Array join at constructing long strings,这个问题被管理员直接关闭了,因此看不到有人给出答案,但问题确实有点意思,毕竟我不确定,于是这里就测试并记录下。

Benchmark

测试数据及代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var arr = Array(10000)
.fill(1)
.map(() => 'A' + Math.ceil(Math.random() * 100));


// array.join
var res=arr.join('; ');

// string literal
var finalString2 = arr.reduce((res, item) => {
return `${res}; ${item}`;
}, '');

// string concatenation
var finalString3 = arr.reduce((res, item) => {
return res + '; ' + item;
}, '');

测试结果如下,可以看出array.join的性能最佳,我尝试改变样本数据量即数组长度,但结果还是很固定。

阅读全文 »

12036最难的应该是班次查询买票,但前端性能也可以做的更好,这里以前端视角来分析下页面性能可以优化的项。

  1. HTML,CSS,JS没有做压缩,通过Webpack等打包工具去除空格,换行等
  2. GZIP/BR压缩开启,体积可以进一步缩小,降低带宽开销2/3
  3. 全部使用的协商缓存,强缓存设置的0,这样带来了部分没必要的请求代价,应该两种结合使用
  4. HTTP2.0应该开启,实现多路复用,请求效率更高
  5. CDN静态资源,实现域名分片
  6. 部分JS,CSS通过Webpack等打包工具bundle到一起,进一步降低请求次数
  7. 懒加载部分资源比如非可见的图片,及部分数据请求

以上即观察后发现可以优化的项。

Chrome Dev Tools中有LightHouse可以对网站性能作出测试,同时给出优化建议,试了下,60分。so,还是有很多优化空间的。

阅读全文 »

window.opener并非JS新特性,但有时却被忽视了,这里总结下它的价值

window.opener作用

The Window interface’s **opener** property returns a reference to the window that opened the window, either with open(), or by navigating a link with a target attribute.

即opener赋予了操作另一个文档的能力,当然不是每一个页面都可以。

这种能力还是有用武之地的,举个例子,A页面点击连接打开了B页面,我现在希望B在点击某个按钮时,A刷新,如何实现呢,opener也许就可以。

阅读全文 »
0%