xml地图|网站地图|网站标签 [设为首页] [加入收藏]
自定义标签在IE6,一个前端开垦程序员的Vim跟I
分类:web前端

登录工程:现代Web应用中的身份验证技术

2017/05/10 · 基础技术 · WEB, 登录

本文作者: 伯乐在线 - ThoughtWorks 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

“登录工程”的前两篇文章分别介绍了《传统Web应用中的身份验证技术》,以及《现代Web应用中的典型身份验证需求》,接下来是时候介绍适应于现代Web应用中的身份验证实践了。

自定义标签在IE6-8的困境

2015/07/20 · HTML5 · IE, 自定义标签

原文出处: 司徒正美   

或许未来前端组件化之路都是自定义标签,但这东西早在20年前,JSTL已在搞了。现在Web Component还只有webkit支持。但一个组件库,还需要一个特殊的标识它们是一块的。不过这个XML已经帮我们搞定了,使用scopeName,如”<xxx:dialog>”。在我继续往下想如何处理如何为这个标签绑定数据,与其他组件通信,管理生命周期,等等大事之前,我还有一个不得不面对的问题,就是如何兼容IE6-8!

比如以下一个页面:

图片 1

在chrome, firefox, IE11, IE11的IE6兼容模式分别如下:

图片 2
图片 3
图片 4
图片 5

我们会发现IE6下实际是多出许多标签,它是把闭标签也变成一个独立的元素节点

图片 6

这个AA:DIV标签被开膛破肚,里面子节点全部暴出来,成为其兄弟节点了。因此想兼容它,就要费点劲。有个两个情况需要考虑,1是用户已经将它写在页面上,情况同上;2是用户是将它放在字符串模版中,这个用正则搞定。不过正则要是碰上复杂的属性名,还是会晕掉。因此我还是打算使用原生的HTML parser。换言之,字符串,我还是会将它变成节点。这么办呢?!我想了许多办法,后来还是使用VML的命名空间法搞定!

我们将上面的页面改复杂点,再看看效果!

图片 7
图片 8

可以看到其套嵌关系现在完全正确,并且标签名不会大写化,也不会生成多余节点!

好了,我们再判定一下是否为自定义标签,或者准确地说,这个节点是否我们组件库中定义的自定义标签。某些情况下,一个页面可以存在多套组件库,包括avalon的,ploymer的,或者是直接用Web Component写的。

avalon的组件库将使用命名空间,这样就好区别开。在IE6-9中,判定element.scopeName是否为aa(这是组件库的命名空间,你可以改个更高大上的名字),在其他浏览器判定此元素的localName是否以aa:开头就行了!

JavaScript

function isWidget(el, uiName){ return el.scopeName ? el.scopeName === uiName: el.localName.indexOf(uiName+":") === 0 }

1
2
3
function isWidget(el, uiName){
  return   el.scopeName ? el.scopeName === uiName: el.localName.indexOf(uiName+":") === 0
}

这个难题解决后,我们就可以开搞基于自定义标签的UI库了!

1 赞 1 收藏 评论

图片 9

一个前端开发工程师的Vim跟IDE一样

2017/01/18 · 基础技术 · vim

原文出处: 小弟调调   

这里是我新配置出来的 jaywcjlove/vim-web 一直在打磨中,基本上可以用了。拿出来骗 star 先上图

图片 10

登录系统

首先,我们要为“登录”做一个简要的定义,令后续的讲述更准确。之前的两篇文章有意无意地混淆了“登录”与“身份验证”的说法,因为在本篇之前,不少“传统Web应用”都将对身份的识别看作整个登录的过程,很少出现像企业应用环境中那样复杂的情景和需求。但从之前的文章中我们看到,现代Web应用对身份验证相关的需求已经向复杂化发展了。

我们有必要重新认识一下登录系统。登录指的是从识别用户身份,到允许用户访问其权限相应的资源的过程。举个例子,在网上买好了票之后去影院观影的过程就是一个典型的登录过程:我们先去取票机,输入验证码取票;接着拿到票去影厅检票进入。取票的过程即身份验证,它能够证明我们拥有这张票;而后面检票的过程,则是授权访问的过程。之所以要分成这两个过程,最直接的原因还是业务形态本身具有复杂性——如果观景过程是免费匿名的,也就免去了这些过程。

图片 11

在登录的过程中,“鉴权”与“授权”是两个最关键的过程。接下来要介绍的一些技术和实践,也包含在这两个方面中。虽然现代Web应用的登录需求比较复杂,但只要处理好了鉴权和授权两个方面,其余各个方面的问题也将迎刃而解。在现代Web应用的登录工程实践中,需要结合传统Web应用的典型实践,以及一些新的思路,才能既解决好登录需求,又能符合Web的轻量级架构思路。

安装

最新版本的Vim 7.4+ 使用(brew install macvim)安装,vim 版本更新 brew install macvim --override-system-vim

Shell

$ git clone ~/.vim $ ln -s ~/.vim/.vimrc ~/.vimrc # 上面执行完成之后 # 开始下载安装插件 $ vim # 在vim中运行 ":PlugInstall" # 上面插件安装完成之后执行下面内容 # command-t 文件搜索插件安装 $ cd ~/.vim/plugged/command-t $ rake make # 搜索文本内容工具 # 需要安装 CtrlSF的依赖ripgrep $ brew install ripgrep # 代码提示插件也需要你运行安装哦,不然没有效果嘞 cd ~/.vim/plugged/YouCompleteMe ./install.sh # 需要安装ctags 不然配置没效果哦 # ctags for Mac $ brew install ctags # ctags for Centos7 $ yum install ctags

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ git clone https://github.com/jaywcjlove/vim-web.git ~/.vim
$ ln -s ~/.vim/.vimrc ~/.vimrc
 
# 上面执行完成之后
# 开始下载安装插件
$ vim # 在vim中运行 ":PlugInstall"
 
# 上面插件安装完成之后执行下面内容
# command-t 文件搜索插件安装
$ cd ~/.vim/plugged/command-t
$ rake make
 
# 搜索文本内容工具
# 需要安装 CtrlSF的依赖ripgrep
$ brew install ripgrep
 
# 代码提示插件也需要你运行安装哦,不然没有效果嘞
cd ~/.vim/plugged/YouCompleteMe
./install.sh
 
# 需要安装ctags 不然配置没效果哦
# ctags for Mac
$ brew install ctags
# ctags for Centos7
$ yum install ctags

注: 默认已经安装了前端必备插件。.vimrc 是控制 vim 行为的配置文件,位于 ~/.vimrc,不论 vim 窗口外观、显示字体,还是操作方式、快捷键、插件属性均可通过编辑该配置文件将 vim 调教成最适合你的编辑器。

解析常见的登录场景

在简单的Web系统中,典型的鉴权也就是要求用户输入并比对用户名和密码的过程,而授权则是确保会话Cookie存在。而在稍微复杂的Web系统中,则需要考虑多种鉴权方式,以及多种授权场景。上一篇文章中所述的“多种登录方式”和“双因子鉴权”就是多种鉴权方式的例子。有经验的人经常调侃说,只要理解了鉴权与授权,就能清晰地理解登录系统了。不光如此,这也是安全登录系统的基础所在。

鉴权的形式丰富多彩,有传统的用户名密码对、客户端证书,有人们越来越熟悉的第三方登录、手机验证,以及新兴的扫码和指纹等方式,它们都能用于对用户的身份进行识别。在成功识别用户之后,在用户访问资源或执行操作之前,我们还需要对用户的操作进行授权。

图片 12

在一些特别简单的情形中——用户一经识别,就可以无限制地访问资源、执行所有操作——系统直接对所有“已登录的人”放行。比如高速公路收费站,只要车辆有合法的号牌即可放行,不需要给驾驶员发一张用于指示“允许行驶的方向或时间”的票据。除了这类特别简单的情形之外,授权更多时候是比较复杂的工作。

在单一的传统Web应用中,授权的过程通常由会话Cookie来完成——只要服务器发现浏览器携带了对应的Cookie,即允许用户访问资源、执行操作。而在浏览器之外,例如在Web API调用、移动应用和富 Web 应用等场景中,要提供安全又不失灵活的授权方式,就需要借助令牌技术。

查看配置位置

Shell

# 进入vim输入下面字符 :echo $MYVIMRC

1
2
# 进入vim输入下面字符
:echo $MYVIMRC

令牌

令牌是一个在各种介绍登录技术的文章中常被提及的概念,也是现代Web应用系统中非常关键的技术。令牌是一个非常简单的概念,它指的是在用户通过身份验证之后,为用户分配的一个临时凭证。在系统内部,各个子系统只需要以统一的方式正确识别和处理这个凭证即可完成对用户的访问和操作进行授权。在上文所提到的例子中,电影票就是一个典型的令牌。影厅门口的工作人员只需要确认来客手持印有对应场次的电影票即视为合法访问,而不需要理会客户是从何种渠道取得了电影票(比如自行购买、朋友赠予等),电影票在本场次范围内可以持续使用(比如可以中场出去休息等)、过期作废。通过电影票这样一个简单的令牌机制,电影票的出售渠道可以丰富多样,检票人员的工作却仍然简单轻松。

图片 13

从这个例子也可以看出令牌并非什么神奇的机制,只是一种很常见的做法。还记得第一篇文章中所述的“自包含的Cookie”吗?那实际上就是一个令牌而已,而且在令牌中写有关于有效性的内容——正如一个电影票上会写明场次与影厅编号一样。可见,在Web安全系统中引入令牌的做法,有着与传统场合一样的妙用。在安全系统中,令牌经常用于包含安全上下文信息,例如被识别的用户信息、令牌的颁发来源、令牌本身的有效期等。另外,在必要时可以由系统废止令牌,在它下次被使用用于访问、操作时,用户被禁止。

由于令牌有这些特殊的妙用,因此安全行业对令牌标准的制定工作一直没有停止过。在现代化Web系统的演进过程中,流行的方式是选用基于Web技术的“简单”的技术来代替相对复杂、重量级的技术。典型地,比如使用JSON-RPC或REST接口代替了SOAP格式的服务调用,用微服务架构代替了SOA架构等等。而适用于Web技术的令牌标准就是Json Web Token(JWT),它规范了一种基于JSON的令牌的简单格式,可用于安全地封装安全上下文信息。

插件管理

这里面刚开始使用的Vim插件管理工具VundleVim/Vundle.vim,后面为了大家安装方便,使用了 junegunn/vim-plug,这个插件管理工具,俺十分不喜欢,多了个 autoload 目录,安装过程也奇丑无比,安装快速,所以就使用它吧,下面命令更新安装的 plug.vim,默认已经有了不需要这一步。

Shell

curl -fLo ~/.vim/autoload/plug.vim --create-dirs

1
2
curl -fLo ~/.vim/autoload/plug.vim --create-dirs
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

OAuth 2、Open ID Connect

令牌在广为使用的OAuth技术中被采用来完成授权的过程。OAuth是一种开放的授权模型,它规定了一种供资源拥有方与消费方之间简单又直观的交互方法,即从消费方向资源拥有方发起使用AccessToken(访问令牌)签名的HTTP请求。这种方式让消费方应用在无需(也无法)获得用户凭据的情况下,只要用户完成鉴权过程并同意消费方以自己的身份调用数据和操作,消费方就可以获得能够完成功能的访问令牌。OAuth简单的流程和自由的编程模型让它很好地满足了开放平台场景中授权第三方应用使用用户数据的需求。不少互联网公司建设开放平台,将它们的用户在其平台上的数据以 API 的形式开放给第三方应用来使用,从而让用户享受更丰富的服务。

图片 14

OAuth在各个开放平台的成功使用,令更多开发者了解到它,并被它简单明确的流程所吸引。此外,OAuth协议规定的是授权模型,并不规定访问令牌的数据格式,也不限制在整个登录过程中需要使用的鉴权方法。人们很快发现,只要对OAuth进行合适的利用即可将其用于各种自有系统中的场景。例如,将 Web 服务视作资源拥有方,而将富Web应用或者移动应用视作消费方应用,就与开放平台的场景完全吻合。

另一个大量实践的场景是基于OAuth的单点登录。OAuth并没有对鉴权的部分做规定,也不要求在握手交互过程中包含用户的身份信息,因此它并不适合作为单点登录系统来使用。然而,由于OAuth的流程中隐含了鉴权的步骤,因而仍然有不少开发者将这一鉴权的步骤用作单点登录系统,这也俨然衍生成为一种实践模式。更有人将这个实践进行了标准化,它就是Open ID Connect——基于OAuth的身份上下文协议,通过它即可以JWT的形式安全地在多个应用中共享用户身份。接下来,只要让鉴权服务器支持较长的会话时间,就可以利用OAuth为多个业务系统提供单点登录功能了。

图片 15

我们还没有讨论OAuth对鉴权系统的影响。实际上,OAuth对鉴权系统没有影响,在它的框架内,只是假设已经存在了一种可用于识别用户的有效机制,而这种机制具体是怎么工作的,OAuth并不关心。因此我们既可以使用用户名密码(大多数开放平台提供商都是这种方式),也可以使用扫码登录来识别用户,更可以提供诸如“记住密码”,或者双因子验证等其他功能。

安装插件

将配置信息其加入 ~/.vim/.vimrc 中的call plug#begin()call plug#end() 之间,最后进入 vim 输入下面命令,摁 enter 进行安装。

Shell

:PlugInstall

1
:PlugInstall

汇总

上面罗列了大量术语和解释,那么具体到一个典型的Web系统中,又应该如何对安全系统进行设计呢?综合这些技术,从端到云,从Web门户到内部服务,本文给出如下架构方案建议:

推荐为整个应用的所有系统、子系统都部署全程的HTTPS,如果出于性能和成本考虑做不到,那么至少要保证在用户或设备直接访问的Web应用中全程使用HTTPS。

用不同的系统分别用作身份和登录,以及业务服务。当用户登录成功之后,使用OpenID Connect向业务系统颁发JWT格式的访问令牌和身份信息。如果需要,登录系统可以提供多种登录方式,或者双因子登录等增强功能。作为安全令牌服务(STS),它还负责颁发、刷新、验证和取消令牌的操作。在身份验证的整个流程的每一个步骤,都使用OAuth及JWT中内置的机制来验证数据的来源方是可信的:登录系统要确保登录请求来自受认可的业务应用,而业务在获得令牌之后也需要验证令牌的有效性。

在Web页面应用中,应该申请时效较短的令牌。将获取到的令牌向客户端页面中以httponly的方式写入会话Cookie,以用于后续请求的授权;在后绪请求到达时,验证请求中所携带的令牌,并延长其时效。基于JWT自包含的特性,辅以完备的签名认证,Web 应用无需额外地维护会话状态。

图片 16

在富客户端Web应用(单页应用),或者移动端、客户端应用中,可按照应用业务形态申请时效较长的令牌,或者用较短时效的令牌、配合专用的刷新令牌使用。

在Web应用的子系统之间,调用其他子服务时,可灵活使用“应用程序身份”(如果该服务完全不直接对用户提供调用),或者将用户传入的令牌直接传递到受调用的服务,以这种方式进行授权。各个业务系统可结合基于角色的访问控制(RBAC)开发自有专用权限系统。

作为工程师,我们不免会考虑,既然登录系统的需求可能如此复杂,而大家面临的需求在很多时候又是如此类似,那么有没有什么现成(Out of Box)的解决方案呢?自然是有的。IdentityServer是一个完整的开发框架,提供了普通登录到OAuth和Open ID Connect的完整实现;Open AM是一个开源的单点登录与访问管理软件平台;而Microsoft Azure AD和AWS IAM则是公有云上的身份服务。几乎在各个层次都有现成的方案可用。使用现成的产品和服务,能够极大地缩减开发成本,尤其为创业团队快速构建产品和灵活变化提供更有力的保障。

本文简单解释了登录过程中所涉及的基本原理,以及现代Web应用中用于身份验证的几种实用技术,希望为您在开发身份验证系统时提供帮助。现代Web应用的身份验证需求多变,应用本身的结构也比传统的Web应用更复杂,需要架构师在明确了登录系统的基本原理的基础之上,灵活利用各项技术的优势,恰到好处地解决问题。

登录工程的系列文章到此就全部结束了,欢迎就文章内容提供反馈。

1 赞 2 收藏 评论

更新插件

插件更新频率较高,差不多每隔一个月你应该看看哪些插件有推出新版本,批量更新,只需在 vim 中执行下面命令即可。

Vim

:PlugUpdate

1
:PlugUpdate

关于作者:ThoughtWorks

图片 17

ThoughtWorks是一家全球IT咨询公司,追求卓越软件质量,致力于科技驱动商业变革。擅长构建定制化软件产品,帮助客户快速将概念转化为价值。同时为客户提供用户体验设计、技术战略咨询、组织转型等咨询服务。 个人主页 · 我的文章 · 84 ·   

图片 18

卸载插件

先在 .vimrc 中注释或者删除对应插件配置信息,然后在 vim 中执行下面命令,即可删除对应插件。

Vim

:PlugClean

1
:PlugClean

启动Vim

Shell

$ vim

1
$ vim

常用快捷键

这里的快捷键是我配置好的可用的。

Vim

;fl # 换出菜单列表 nw # 窗口切换 ;lw # 跳转至右方的窗口 ;hw # 跳转至左方的窗口 ;kw # 跳转至上方的子窗口 ;jw # 跳转至下方的子窗口 # 可以直接在Tab之间切换。 gt # 后一个Tab标签 gT # 前一个Tab标签 ;q # 关闭一个标签 ctrl-f # 下一页 f 就是`forword` ctrl-b # 上一页 b 就是`backward` ;t # 通过搜索文件打开文件 # 快速文本内定位 ;;b # 光标前代码定位 ;;e # 光标后代码定位 ;;f # 光标后代码定位 <搜索自负> 出现定位信息 ;;F # 光标前代码定位 <搜索自负> 出现定位信息 ;ilt # 设置显示/隐藏标签列表子窗口(函数列表)的快捷键。速记:identifier list by tag 0 # 行首 $ # 行尾 :r ~/git/R.js # 将文件内容导入到该文件中 :!which ls # 找命令不推出vim运行命令 :!date # 查看编辑时间 :r !date # 将当前编辑时间导入当前文本光标所在行 U # 选中 - 变大写 u # 选中 - 变小写 ~ # 选中 - 变大写变小写,小写变大写 ;cc # 代码注释"//" ;cm # 代码段落注释"/**/" ;ci # 注释相反,注释的取消注释,没注释的注释 ;cs # 段落注释,注释每行前面加"*" ;c$ # 光标开始到行结束的位置注释 ;cA # 在行尾部添加注释符"//" ;cu # 取消代码注释 za # 单个代码折叠 zM # 折叠左右代码 zR # 所有代码折叠取消 ;i # 开/关缩进可视化 > # 代码锁进 - 选中摁尖括号 < # 代码锁进 - 选中摁尖括号 :1,24s/header/www/g # 第1到24行将header替换成www <c-z> # 退出Vim

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
;fl # 换出菜单列表
nw  # 窗口切换
;lw # 跳转至右方的窗口
;hw # 跳转至左方的窗口
;kw # 跳转至上方的子窗口
;jw # 跳转至下方的子窗口
 
 
# 可以直接在Tab之间切换。
gt # 后一个Tab标签
gT # 前一个Tab标签
;q # 关闭一个标签
 
ctrl-f # 下一页 f 就是`forword`
ctrl-b # 上一页 b 就是`backward`  
 
;t # 通过搜索文件打开文件
 
# 快速文本内定位
;;b # 光标前代码定位
;;e # 光标后代码定位
;;f # 光标后代码定位 <搜索自负> 出现定位信息
;;F # 光标前代码定位 <搜索自负> 出现定位信息
 
;ilt # 设置显示/隐藏标签列表子窗口(函数列表)的快捷键。速记:identifier list by tag
 
0   # 行首
$   # 行尾
 
:r ~/git/R.js # 将文件内容导入到该文件中
:!which ls  # 找命令不推出vim运行命令
:!date      # 查看编辑时间
:r !date    # 将当前编辑时间导入当前文本光标所在行
 
U # 选中 - 变大写
u # 选中 - 变小写
~ # 选中 - 变大写变小写,小写变大写
 
;cc # 代码注释"//"
;cm # 代码段落注释"/**/"
;ci # 注释相反,注释的取消注释,没注释的注释
;cs # 段落注释,注释每行前面加"*"
;c$ # 光标开始到行结束的位置注释
;cA # 在行尾部添加注释符"//"
;cu # 取消代码注释
 
za # 单个代码折叠
zM # 折叠左右代码
zR # 所有代码折叠取消
 
;i  # 开/关缩进可视化
>   # 代码锁进 - 选中摁尖括号
<   # 代码锁进 - 选中摁尖括号
 
:1,24s/header/www/g  # 第1到24行将header替换成www
 
<c-z>  # 退出Vim

基础使用

  • inoremap (Insert Mode)就只在插入(insert)模式下生效
  • vnoremap (Visual Mode)只在visual模式下生效
  • nnoremap (Normal Mode)就在normal模式下(狂按esc后的模式)生效
  • 快捷键<c-y>, 标示(Ctrly,)

快捷键通配符

快捷键通配符 <leader> 相当于是一个通用的命令符,默认好像是,你可以在.vimrc中将他改为任意一个按键,在我们这个配置我改为了冒号;

Vim

" 定义快捷键的前缀,即 <Leader> let mapleader=";"

1
2
" 定义快捷键的前缀,即 <Leader>
let mapleader=";"

插入命令

Vim

a # → 在光标所在字符后插入 A # → 在光标所在字符尾插入 i # → 在光标所在字符前插入 I # → 在光标所在行行首插入 o # → 在光标下插入新行 O # → 在光标上插入新行

1
2
3
4
5
6
a # → 在光标所在字符后插入  
A # → 在光标所在字符尾插入  
i # → 在光标所在字符前插入  
I # → 在光标所在行行首插入  
o # → 在光标下插入新行  
O # → 在光标上插入新行

删除命令

Vim

x # → 删除关闭所在处字符 nx # → 删除关闭所在处n个字符 dd # → 删除光标所在行, ndd # → 删除n行 dG # → 删除光标所在行到文件末尾内容 D # → 删除光标所在处到行尾内容 :n1,n2d # → 删除指定范围的行 如:1,2d

1
2
3
4
5
6
7
x   # → 删除关闭所在处字符  
nx  # → 删除关闭所在处n个字符  
dd  # → 删除光标所在行,
ndd # → 删除n行  
dG  # → 删除光标所在行到文件末尾内容  
D   # → 删除光标所在处到行尾内容  
:n1,n2d # → 删除指定范围的行 如:1,2d

定位命令

Vim

:set number #→ 设置行号 简写set nu :set nonu #→ 取消行号 gg #→ 到第一行 G #→ 到最后一行 nG #→ 到第n行 :n #→ 到第n行 S #→ 移至行尾 0 #→ 移至行尾 hjkl #→ 前下上后 w #→ 到下一个单词的开头 b #→ 与w相反 e #→ 到下一个单词的结尾。 ge #→ 与e相反 0 #→ 到行头 ^ #→ 到本行的第一个非blank字符 $ #→ 到行尾 g_ #→ 到本行最后一个不是blank字符的位置。 fa #→ 到下一个为a的字符处,你也可以fs到下一个为s的字符。 t, #→ 到逗号前的第一个字符。逗号可以变成其它字符。 3fa #→ 在当前行查找第三个出现的a。 F 和 T → 和 f 和 t 一样,只不过是相反方向。 zz # 将当前行置于屏幕中间(不是转载…) zt # 将当前行置于屏幕顶端(不是猪头~) zb # 底端啦~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
:set number   #→ 设置行号 简写set nu  
:set nonu   #→ 取消行号  
gg  #→ 到第一行  
G   #→ 到最后一行  
nG  #→ 到第n行  
:n  #→ 到第n行  
S   #→ 移至行尾  
0   #→ 移至行尾  
hjkl #→ 前下上后  
 
w   #→ 到下一个单词的开头  
b   #→ 与w相反  
e   #→ 到下一个单词的结尾。  
ge  #→ 与e相反  
 
0   #→ 到行头  
^   #→ 到本行的第一个非blank字符  
$   #→ 到行尾  
g_  #→ 到本行最后一个不是blank字符的位置。  
fa  #→ 到下一个为a的字符处,你也可以fs到下一个为s的字符。  
t,  #→ 到逗号前的第一个字符。逗号可以变成其它字符。  
3fa #→ 在当前行查找第三个出现的a。  
F 和 T → 和 f 和 t 一样,只不过是相反方向。  
 
zz # 将当前行置于屏幕中间(不是转载…)  
zt # 将当前行置于屏幕顶端(不是猪头~)  
zb # 底端啦~

本文由澳门新葡亰手机版发布于web前端,转载请注明出处:自定义标签在IE6,一个前端开垦程序员的Vim跟I

上一篇:跨域访问和防盗链基本原理,我也想来谈谈HTTP 下一篇:入门教程,控制台不完全指南澳门新葡亰手机版
猜你喜欢
热门排行
精彩图文