版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30856231/article/details/78087376
009_css预处理器less sass saml sso 单点登录 websocket ## less 安装: npm install -g less 命令: lessc style.less style.css > 注意: .rect( 123, 456, 789){} 括号中是‘,’逗号,不能用“;” 分号 【1】LESS是基于JavaScript运行,所以LESS是在客户端处理;Sass是基于Ruby的,是在服务器端处理的. 【2】sass支持老的语法,可以不包含花括号和分号 【3】sass的变量必须是$开始,然后变量名和值使用冒号隔开,跟css的属性一致 【4】sass: @include引入 less: .class 引入 变量、嵌套、mixin(混合)、继承、导入(import)、颜色函数、 混合方法不一样, sass: @mixin error($borderWidth: 2px) { border: $borderWidth solid #F00; color: #F00; } less: .error(@borderWidth: 2px) { border: @borderWidth solid #F00; color: #F00; } .rect(@width1:100px,@height1:100px) { width: @width1; height: @height1; } 定义变量: @base: #ff6700; .centerss{ position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } 调用: div { .centerss(); } css预处理器 ## 区别 http://www.cnblogs.com/wangpenghui522/p/5467560.html 1.编译环境不一样 Sass的安装需要Ruby环境,是在服务端处理的,而Less是需要引入less.js来处理Less代码输出css到浏览器,也可以在开发环节使用Less,然后编译成css文件, 直接放到项目中,也有 Less.app、SimpleLess、CodeKit.app这样的工具,也有在线编译地址。 2.变量符不一样,Less是@,而Scss是$,而且变量的作用域也不一样。 3.Sass支持条件语句,可以使用if{}else{},for{}循环等等。而Less不支持。 ## SASS . Sass简介 Sass 是一种css预处理器,CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。 /* 变量默认只能在属性值中使用 差值: 选址器和属性部分用差值 #{$s} */ $a:13; $a:12 !default; //默认 @debug $a; $aa: 10rem; $b: 10px; $c: null; @debug $aa; @debug $b; @debug $c; $d: $a * 2; $border: '1px solid black'; @debug $d; @if ($a > 7){ } npm install -g node-sass 安装node-sass的软件 node-sass -v npm install -g cnpm //中文版 npm 命令改为: cnpm install -g node-sass 任何一个文件中都有 两个文件夹 . .. . 当前文件夹 .. 上一层 cmd中复制命令:右键--标记--回车 C:\Users\Administrator\AppData\Roaming\npm 把文件拖过去 node-sass -w index.scss index.css node-sass -w index.scss index.css --output-style expanded ### 占位符 % 生成高效率群组选择器 % 继承的方法 --> 群组选择器 ### 扩展/继承(@extend) %mt5 { margin-top: 5px; } %pt5{ padding-top: 5px; } .btn { @extend %mt5; @extend %pt5; } ### for 循环 @for $i from 1 through $num{ #{$box}:nth-child(#{$i}){ animation: drop 1s cubic-bezier(0.38, 1.48, 0.22, 1.32) ( $i - 1 ) * 0.1s both; } } ### each 遍历 $arr: 'one','two','three'; @each $v in $arr{ .atem-#{$v}{ color:red; } } /*html中遍历: foreach($data as $v){ }*/ ## 单点登录 saml sso 基于SAML的单点登录介绍 http://blog.csdn.net/csethcrm/article/details/20694993 单点登录SSO(cookie和ticket)实现 http://blog.csdn.net/z1729734271/article/details/52425746 基于 SAML 的 WebSphere Application Server 单点登录的场景设计 https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1012_zhangt_saml/1012_zhangt_saml.html **SAML 作用** SAML 主要包括三个方面: 1.认证申明。表明用户是否已经认证,通常用于单点登录。 2.属性申明。表明 某个Subject 的属性。 3.授权申明。表明 某个资源的权限。 它是一个基于XML的标准,用于 **在不同的安全域(security domain)之间交换认证和授权数据**。 SAML Assertions 断言:定义交互的数据格式 (XML) SAML Protocols 协议:定义交互的消息格式 (XML+processing rules) ** [请求--响应协议] ** SAML Bindings 绑定:定义如何与常见的通信协议绑定 (HTTP,SOAP) SAML Profile 使用框架:给出对 SAML 断言及协议如何使用的建议 (Protocols+Bindings) > 在 SAML 协议标准中出现的两个角色, 一个是 Identity Provider(IdP)【身份提供者, 身份提供商】,通常 IdP 负责创建、维护和管理用户认证。 一个是 Service Provider(SP)【服务提供者, 服务提供者】,通常 SP 控制用户是否能够使用该 SP 提供的服务和资源。 登录成功后,系统会自动给你的浏览器设置cookie,证明你已经登录过了。 当你再访问这个应用的需要保护的URL的时候,系统还是要进行安全检查的,但是这次系统能够发现相应的cookie。 上图就是一个利用cookie做单点登录的原理图,案例为用户dgh(密码123)登录www.qiandu.com,之后又登录mail.qiandu.com。流程如下: 第一步:用户输入用户名/密码(dgh/123)登录到www.qiandu.com。 第二步:www.qiandu.com处理登录逻辑,并且将用户信息通过cookie的方式返回到客户端(最好加密用户信息)。 第三步:用户访问mail.qiandu.com,浏览器自动将用户信息携带到mail.qiandu.com,通过过滤器(filter)处理用户的登录请求。 第四步:过滤器从cookie中获取用户信息,登录,返回用户访问界面。这样用户就只登录一次,就访问了两个网站了。 1. user访问应用服务 2. [点登录]WEB APP1 生成SAML请求 --> 3. 定向到浏览器访问SSO URL --> 4. [login get'/sso'] 统一认证中心 解析SAML请求,需提供有效登陆凭证或cookie信息进行认证。 --> 跳转到登录页面 输入ID password --> 5. [callback.js post'/sso'] 进行认证,认证成功,以cookie方式存储用户相关信息,构造断言,生成SAML响应。 --> 6. 编码后的响应定向到浏览器访问ACS 7. WEB APP1 使用IDP的公钥验证SAML响应。验证成功,登录app。 ## shell 同时它又是一种程序设计语言。作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令; 作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。 文字操作系统与外部最主要的接口就叫做shell。shell是操作系统最外面的一层。shell管理你与操作系统之间的交互:等待你输入, 向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果。 ## websocket socket.io Websocket是什么? Websocket是一种协议,它本质上是一个基于TCP的协议,它由通信协议和编程API组成,WebSocket能够在浏览器和服务器之间建立双向连接, 以基于事件的方式,赋予浏览器实时通信能力。既然是双向通信,就意味着服务器端和客户端可以同时发送并响应请求,而不再像HTTP的请求和响应。 为了建立一个WebSocket连接,客户端浏览器首先要向服务器发起一个HTTP请求,这个请求和通常的HTTP请求不同,包含了一些附加头信息, 其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的HTTP请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端, 客户端和服务器端的 WebSocket连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的 某一方主动的关闭连接 websocket的产生背景 在Websocket出现之前,浏览器与服务器之间通过http只能实现单向的通信。在此之前,要实现浏览器之间的即时通信,一般采用Comet来模拟。 Comet是一种服务器向页面推送消息的技术,这种技术可以让信息实时推送到页面,也算是可以比较完整地实现实时通信,但是效率低下。 实现Comet的方式主要有两种,一种是轮询(polling),一种是流。 轮询,就是客户端通过一定的时间间隔以频繁请求的方式向服务器发送请求,来保持客户端和服务器端的数据同步。问题很明显,当客户端以固定频率向服 务器端发送请求时,服务器端的数据可能并没有更新,带来很多无谓请求,浪费带宽,效率低下。 第二种实现Comet的是HTTP流。流不同于轮询,它在页面的整个生命周期内只使用一个HTTP连接,通过服务器端语言的缓冲区刷新机制来将消息推送出去。 除了Comet,通过Flash的API也是可以实现Socket的。AdobeFlash 通过自己的 Socket 实现完成数据交换,再利用 Flash 暴露出相应的接口为 JavaScript 调用,从而达到实时传输目的。此方式比轮询要高效,但是随着今年Flash正式宣告退出历史舞台,这种方式现在的存在意义不大。 由此看出,传统 Web 模式在处理高并发及实时性需求的时候,会遇到难以逾越的瓶颈,我们需要一种高效节能的双向通信机制来保证数据的实时传输。 在此背景下,基于 HTML5 规范的、有 Web TCP 之称的 WebSocket 应运而生。 websocket的实现原理 在实现websocket连线过程中,需要通过浏览器发出websocket连线请求,然后服务器发出回应,这个过程通常称为“握手” 。在 WebSocket API, 浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。 ### Socket.io模块 Socket.io是基于Nodejs生态的,但是做Nodejs所不能实现的WebSocket的库。就像Express之于Nodejs、jQuery之于Javascript, ***Socket.io是对Node语言关于WebSocket所有API的封装和拓展,是一个应用框架。*** Socket.IO是一个开源的WebSocket库,它通过Node.js实现WebSocket服务端,同时也提供客户端JS库。Socket.IO支持以事件为基础的实时双向通讯, 它可以工作在任何平台、浏览器或移动设备。 Socket.IO支持4种协议:WebSocket、htmlfile、xhr-polling、jsonp-polling,它会自动根据浏览 器选择适合的通讯方式, 从而让开发者可以聚焦到功能的实现而不是平台的兼容性,同时Socket.IO具有不错的稳定性和性能。 Socket.io的作用主要是将webSocket协议应用到所有的浏览器。该模块主要应用于实时的长连接多请求项目中, 例如在线联网游戏、实时聊天、实时股票查看、二维码扫描登录等。 Socket协议存在服务端和客户端,因此要实现一个socket服务时,根据socket的服务端和客户端API分别实现其逻辑。服务端启动进程等待客户端的连接。 > Socket.io基本使用方法: 【1】服务端: npm install socket.io 安装socket.io var io=require('socket.io').listen(8081); 或者: var app = require('express')(); var server = require('http').Server(app); var io = require('socket.io')(server); 【2】服务端: io.on(‘connection’,function(socket));//监听客户端连接,回调函数会传递本次连接的socket socket.on(‘String’,function(data));//监听客户端发送的信息 例子: socket.on('my other event',function(data){ console.log(data); }); socket.emit(‘String’, data);//给该socket的客户端发送消息 socket.emit('news',{hello:'world'}); socket.on('disconnect', function () {//断开连接 io.emit('user disconnected'); }); 【3】服务端: io.sockets.emit(‘String’,data);//给所有客户端广播消息 io.sockets.socket(socketid).emit(‘String’, data);//给指定的客户端发送消息 广播消息: //给除了自己以外的客户端广播消息 socket.broadcast.emit("msg",{data:"hello,everyone"}); //给所有客户端广播消息 io.sockets.emit("msg",{data:"hello,all"}); 分组 socket.join(room1);//加入room1分组; socket.leave(room1);//退出分组 对分组中的用户发送信息 socket.broadcast.to('group1').emit('event_name', data);//不包括自己 io.sockets.in('group1').emit('event_name', data);//包括自己 broadcast方法允许当前socket client不在该分组内 【4】客户端: 引入js:<script src="js/socket.io.js"></script> <script> var socket=io.connect('http://localhost:8081');//连接服务器 socket.on('news',function(data){ console.log(data); socket.emit('my other event',{clinetMessage:'client data'}); }); </script> 【5】客户端: 客户端socket.on()监听的事件: connect:连接成功 connecting:正在连接 disconnect:断开连接 connect_failed:连接失败 error:错误发生,并且无法被其他事件类型所处理 message:同服务器端message事件 anything:同服务器端anything事件 reconnect_failed:重连失败 reconnect:成功重连 reconnecting:正在重连 当第一次连接时,事件触发顺序为:connecting->connect;当失去连接时,事件触发顺序为:disconnect->reconnecting(可能进行多次)->connecting->reconnect->connect。