xml地图|网站地图|网站标签 [设为首页] [加入收藏]
头部压缩技术介绍,前端防火墙
分类:web前端

征服 JavaScript 面试:类继承和原型继承的区别

2017/01/30 · JavaScript · 继承

原文出处: Eric Elliott   译文出处:众成翻译   

图片 1

图-电子吉他-Feliciano Guimarães(CC BY 2.0)

“征服JavaScript面试”是我所写的一个系列文章,旨在帮助那些应聘中、高级JavaScript开发职位的读者们准备一些常见的面试问题。我自己在实际面试当中也经常会问到这类问题。系列的第一篇文章请参见“什么是闭包”

注:本文均以ES6标准做代码举例。如果想了解ES6,可以参阅“ES6学习指南”

原文链接:https://medium.com/javascript-scene/master-the-javascript-interview-what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9#.d84c324od

对象在JavaScript语言中使用十分广泛,学会如何有效地运用对象,有助于工作效率的提升。而不良的面向对象设计,可能会导致代码工程的失败,更严重的话还会引发整个公司悲剧

不同于其它大部分语言,JavaScript是基于原型的对象系统,而不是基于。遗憾的是,大多数JavaScript开发者对其对象系统理解不到位,或者难以良好地应用,总想按照类的方式使用,其结果将导致代码里的对象使用混乱不堪。所以JavaScript开发者最好对原型和类都能有所了解。

打造双剑合璧的 XSS 前端防火墙

2015/09/30 · HTML5 · XSS

原文出处: 林子杰(@Zack__lin)   

HTTP/2 头部压缩技术介绍

2015/11/03 · HTML5 · HTTP/2

原文出处: imququ(@屈光宇)   

我们知道,HTTP/2 协议由两个 RFC 组成:一个是 RFC 7540,描述了 HTTP/2 协议本身;一个是 RFC 7541,描述了 HTTP/2 协议中使用的头部压缩技术。本文将通过实际案例带领大家详细地认识 HTTP/2 头部压缩这门技术。

类继承和原型继承有何区别?

这个问题比较复杂,大家有可能会在评论区各抒己见、莫衷一是。因此,列位看官需要打起十二分的精神学习个中差异,并将所学良好地运用到实践当中去。

类继承:可以把类比作一张蓝图,它描绘了被创建对象的属性及特征。

众所周知,使用new关键字调用构造函数可以创建类的实例。在ES6中,不用class关键字也可以实现类继承。像Java语言中类的概念,从技术上来说在JavaScript中并不存在。不过JavaScript借鉴了构造函数的思想。ES6中的class关键字,相当于是建立在构造函数之上的一种封装,其本质依旧是函数。

JavaScript

class Foo {} typeof Foo // 'function'

1
2
class Foo {}
typeof Foo // 'function'

虽然JavaScript中的类继承的实现建立在原型继承之上,但是并不意味二者具有相同的功能:

JavaScript的类继承使用原型链来连接子类和父类的 [[Prototype]],从而形成代理模式。通常情况下,super()_构造函数也会被调用。这种机制,形成了单一继承结构,以及面向对象设计中最紧密的耦合行为

“类之间的继承关系,导致了子类间的相互关联,从而形成了——基于层级的分类。”

原型继承: 原型是工作对象的实例。对象直接从其他对象继承属性。

原型继承模式下,对象实例可以由多个对象源所组成。这样就使得继承变得更加灵活且[[Prototype]]代理层级较浅。换言之,对于基于原型继承的面向对象设计,不会产生层级分类这样的副作用——这是区别于类继承的关键所在。

对象实例通常由工厂函数或者Object.create()来创建,也可以直接使用Object字面定义。

原型是工作对象的实例。对象直接从其他对象继承属性。”

前言

深入接触 xss 注入是从排查业务的广告注入开始,以前对 xss 注入片面认为是页面输入的安全校验漏洞导致一系列的问题,通过对 zjcqoo 的《XSS 前端防火墙》系列文章,认识到自己其实对 XSS 注入的认识还真是半桶水。

为什么要压缩

在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 / 响应头部、消息主体」三部分组成。一般而言,消息主体都会经过 gzip 压缩,或者本身传输的就是压缩过后的二进制文件(例如图片、音频),但状态行和头部却没有经过任何压缩,直接以纯文本传输。

随着 Web 功能越来越复杂,每个页面产生的请求数也越来越多,根据 HTTP Archive 的统计,当前平均每个页面都会产生上百个请求。越来越多的请求导致消耗在头部的流量越来越多,尤其是每次都要传输 UserAgent、Cookie 这类不会频繁变动的内容,完全是一种浪费。

以下是我随手打开的一个页面的抓包结果。可以看到,传输头部的网络开销超过 100kb,比 HTML 还多:

图片 2

下面是其中一个请求的明细。可以看到,为了获得 58 字节的数据,在头部传输上花费了好几倍的流量:

图片 3

HTTP/1 时代,为了减少头部消耗的流量,有很多优化方案可以尝试,例如合并请求、启用 Cookie-Free 域名等等,但是这些方案或多或少会引入一些新的问题,这里不展开讨论。

为什么搞清楚类继承和原型继承很重要?

继承,本质上讲是一种代码重用机制——各种对象可以借此来共享代码。如果代码共享的方式选择不当,将会引发很多问题,如:

使用类继承,会产生父-子对象分类的副作用

这种类继承的层次划分体系,对于新用例将不可避免地出现问题。而且基类的过度派生,也会导致脆弱基类问题,其错误将难以修复。事实上,类继承会引发面向对象程序设计领域的诸多问题:

  • 紧耦合问题(在面向对象设计中,类继承是耦合最严重的一种设计),紧耦合还会引发另一个问题:
  • 脆弱基类问题
  • 层级僵化问题(新用例的出现,最终会使所有涉及到的继承层次上都出现问题)
  • 必然重复性问题(因为层级僵化,为了适应新用例,往往只能复制,而不能修改已有代码)
  • 大猩猩-香蕉问题(你想要的是一个香蕉,但是最终到的却是一个拿着香蕉的大猩猩,还有整个丛林)

对于这些问题我曾做过深入探讨:“类继承已是明日黄花——探究基于原型的面向对象编程思想”

“优先选择对象组合而不是类继承。” ~先驱四人,《设计模式:可复用面向对象软件之道》

里面很好地总结了:

捣蛋的运营商

由于 xss 注入的范围太广,本文仅对网关劫持这一方面的 XSS 注入进行讨论。
这里读者有个小小的疑问,为什么我要选网关劫持进行讨论?因为网关劫持可以大面积范围进行有效控制。

曾经,有这样一道风靡前端的面试题(当然我也现场笔试过):当你在浏览器地址栏输入一个URL后回车,将会发生的事情?其实本文不关心请求发到服务端的具体过程,但是我关心的时,服务端响应输出的文档,可能会在哪些环节被注入广告?手机、路由器网关、网络代理,还有一级运营商网关等等。所以,无论如何,任何网页都得经过运营商网关,而且最调(zui)皮(da)捣(e)蛋(ji)的,就是通过运营商网关。

另外, 也提醒大家,如果手机安装了一些上网加速软件、网络代理软件或设置网络代理 IP,会有安全风险,也包括公共场所/商家的免费 WIFI。

压缩后的效果

接下来我将使用访问本博客的抓包记录来说明 HTTP/2 头部压缩带来的变化。如何使用 Wireshark 对 HTTPS 网站进行抓包并解密,请看我的这篇文章。本文使用的抓包文件,可以点这里下载。

首先直接上图。下图选中的 Stream 是首次访问本站,浏览器发出的请求头:

图片 4

从图片中可以看到这个 HEADERS 流的长度是 206 个字节,而解码后的头部长度有 451 个字节。由此可见,压缩后的头部大小减少了一半多。

然而这就是全部吗?再上一张图。下图选中的 Stream 是点击本站链接后,浏览器发出的请求头:

图片 5

可以看到这一次,HEADERS 流的长度只有 49 个字节,但是解码后的头部长度却有 470 个字节。这一次,压缩后的头部大小几乎只有原始大小的 1/10。

为什么前后两次差距这么大呢?我们把两次的头部信息展开,查看同一个字段两次传输所占用的字节数:

图片 6

图片 7

对比后可以发现,第二次的请求头部之所以非常小,是因为大部分键值对只占用了一个字节。尤其是 UserAgent、Cookie 这样的头部,首次请求中需要占用很多字节,后续请求中都只需要一个字节。

是否所有的继承方式都有问题?

人们说“优先选择对象组合而不是继承”的时候,其实是要表达“优先选择对象组合而不是类继承”(引用自《设计模式》的原文)。该思想在面向对象设计领域属于普遍共识,因为类继承方式的先天缺陷,会导致很多问题。人们在谈到继承的时候,总是习惯性地省略这个字,给人的感觉像是在针对所有的继承方式,而事实上并非如此。

因为大部分的继承方式还是很棒的。

前端防火墙的实践

经过近一段时间通过对 zjcqoo 的《XSS 前端防火墙》六板斧的反复琢磨理解,基本上防御措施可以归为两大类:一种是从协议上屏蔽,一种是从前端代码层面进行拦截移除。通过 zjcqoo 提出的几种注入防御方式,进行几个月的实践观察,对广告注入方式大概可以归为两种:完全静态注入、先静态注入后动态修改(创建)。

  1. 完全静态注入
    完全内联 js、css、和 dom,不管是 body 内外,甚是恶心,而且如果是在监控脚本前面注入的,还可以抢先执行,造成防御不起作用。注入的 DOM 也无法清除。
  2. 先静态注入后动态修改
    这种可以分为几种:一种是异步请求接口数据再生成 DOM 注入,一种是修改 iframe 源地址进行引入,另外一种是修改 script 源地址,请求执行 js 再异步获取数据或生成 DOM。

技术原理

下面这张截图,取自 Google 的性能专家 Ilya Grigorik 在 Velocity 2015 • SC 会议中分享的「HTTP/2 is here, let’s optimize!」,非常直观地描述了 HTTP/2 中头部压缩的原理:

图片 8

我再用通俗的语言解释下,头部压缩需要在支持 HTTP/2 的浏览器和服务端之间:

  • 维护一份相同的静态字典(Static Table),包含常见的头部名称,以及特别常见的头部名称与值的组合;
  • 维护一份相同的动态字典(Dynamic Table),可以动态的添加内容;
  • 支持基于静态哈夫曼码表的哈夫曼编码(Huffman Coding);

静态字典的作用有两个:1)对于完全匹配的头部键值对,例如 : method :GET,可以直接使用一个字符表示;2)对于头部名称可以匹配的键值对,例如 cookie :xxxxxxx,可以将名称使用一个字符表示。HTTP/2 中的静态字典如下(以下只截取了部分,完整表格在这里):

Index Header Name Header Value
1 :authority
2 :method GET
3 :method POST
4 :path /
5 :path /index.html
6 :scheme http
7 :scheme https
8 :status 200
32 cookie
60 via
61 www-authenticate

同时,浏览器可以告知服务端,将 cookie :xxxxxxx 添加到动态字典中,这样后续整个键值对就可以使用一个字符表示了。类似的,服务端也可以更新对方的动态字典。需要注意的是,动态字典上下文有关,需要为每个 HTTP/2 连接维护不同的字典。

使用字典可以极大地提升压缩效果,其中静态字典在首次请求中就可以使用。对于静态、动态字典中不存在的内容,还可以使用哈夫曼编码来减小体积。HTTP/2 使用了一份静态哈夫曼码表(详见),也需要内置在客户端和服务端之中。

这里顺便说一下,HTTP/1 的状态行信息(Method、Path、Status 等),在 HTTP/2 中被拆成键值对放入头部(冒号开头的那些),同样可以享受到字典和哈夫曼压缩。另外,HTTP/2 中所有头部名称必须小写。

本文由澳门新葡亰手机版发布于web前端,转载请注明出处:头部压缩技术介绍,前端防火墙

上一篇:仙剑奇侠传的web移植版,Web开荒者需知的十五个 下一篇:没有了
猜你喜欢
热门排行
精彩图文