函数合成,从右到左合成函数
var compose = function () {
var _arguments = arguments; //缓存外层函数
var length = _arguments.length; //缓存长度
var index = length; //定义游标变量
//检测函数,如果存在非函数参数,则抛出异常
while (index --) {
if (typeof _arguments[index] !== 'function') {
throw new TypeError('参数必须为函数!');
}
}
return function () {
var index = length - 1; //定位到最后一个参数下标
//如果存在两个及以上参数,则调用最后一个参数函数,并传入内层函数;否则直接返回第 1 个参数函数。
var result = length ? _arguments[index].apply(this, arguments) : arguments[0];
//迭代参数函数
while (index -- ) {
//把右侧函数的执行结果作为参数传给左侧参数函数,并调用。
result = _arguments[index](result);
console.log( this)
}
return result; //返回最左侧参数函数的执行结果
}
}
var add = function (x) { return x + 5; } //加法允许
var mul= function (x) { return x * 5; } //乘法运算
var sub= function (x) { return x - 5; } //减法运算
var div = function (x) { return x / 5; } //除法运算
var fn = compose(compose(add, mul), sub, div);
//请问此时输出什么
console.log(fn(50))
说说什么是单点登录?如何实现?
什么是?
单点登录就是Single sign on,简称SSO,就是用户在一个应用中登录之后,其他受信任的相关应用也都能登录,举个例子,淘宝跟天猫是一家公司的不同部门开发的应用,我在淘宝登录后,我会发现天猫也随机登录了,这就是单点登录。
如何实现?
首先我们要明确:
- cookie是不能跨域的
- 每个网站对应的session也是不同的 所以针对这些情况,我们有两种场景需要面对:
- 同一个域名
此时针对不同的域名,比如a.test.com,b.test.com。理论上来说,我们都会有一个登录界面login.test.com(没有也没有关系)。此时我们在login.test.com登录的时候,我们可以设置cookie的域为顶域,即test.com。这样就避免了跨域的问题,而对于session,我们可以做一个统一的common session(Spring Session等方案) - 同一个域名
对于不同的域名,我们有两种方法:
- cookie应用间重定向
如图
我们可以在一个域名下登录之后,不断用cookie向服务器重定向发送其他域名cookie的请求。但是这种方法在面对到比较多的域名的时候,将会非常耗时和消耗性能,建议站点较少时候使用。
- 建立sso系统
流程如下:
- 用户访问当前域名,此时是需要登录的,但用户现在没有登录。
- 跳转到CAS server,即SSO登录系统,SSO系统也没有登录,弹出用户登录页。
- 用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器(Browser)中写入SSO域下的Cookie。
- SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给当前域名。
- 当前域名拿到ST后,从后台向SSO发送请求,验证ST是否有效。
- 验证通过后,当前域名将登录状态写入session并设置当前域下的Cookie。 此时,如果有新的域名需要登录。就会走如下流程:
- 用户访问新的域名,此时是需要登录的,于是跳转到SSO。
- 此时SSO系统已经登录,生成一个ST,然后跳转到新的,同时将ST作为参数传递给新的域名。
- 新的域名拿到ST后,从后台向SSO发送请求,验证ST是否有效。
- 验证通过后,新的域名将登录状态写入session并设置新的域下的Cookie。
为什么还要发ST来验证,直接登录不好嘛?因为存在坏人,如果SSO并没有登录,而对方伪造了一个用户信息,发送到服务器,此时也会判断为登录,则就会造成账号的被盗