作者归档:Rick

ES this的问题

浏览器环境

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this</title>
</head>
<body>
    <script>
        var age = 100
        var rick = {
            age: 30,
            name: 'Rick',
            grow() {
                console.log(`I am ${this.name}, I am ${this.age}`) // age: 30
                setTimeout(function() {
                    console.log(`I am ${this.age}`) // 100
                    console.log(`I am ${window.age}`) // 100
                    console.log(`I am ${age}`) // 100
                    console.log(window === this) // true
                }, 100)

            }
        }

        rick.grow()

        function testThis(param) {
            console.log(param + '. this === window => ' +  (this === window))
        }

        testThis(1) // 作为一个函数的话 this指向global,浏览器环境下就是window
        new testThis(2) // 作为一个对象的话 this指向对象

    </script>
</body>
</html>

node环境

// let age = 100;
age = 100

let rick = {
    age: 30,
    name: 'Rick',
    grow() {
        // console.log(`I am ${this.name}, I am ${this.age}`) // age: 30
        setTimeout(function() {
            console.log(`I am ${this.age}`) // 使用bind(this) age: 30. 否则this函数自身的this
            // console.log(this)

            // for (let k in this) {
            //     console.log(k)
            // }
        }.bind(this), 1001)

    }
}

// rick.grow()

// 数组复制
let a = [1, 2]
let b = [...a]
console.log(b)

// 对象复制
let user = {
    name: 'Jame'
}

let c = Object.assign({}, user) 
console.log(c)
let d = {...user}
console.log(d)

// 数组转函数参数
function test(a, b) {
    console.log(`a: ${a}, b: ${b}`)
    console.log(`2.this => ${this}`)
}
console.log(test(...a))
console.log(test.apply(null, a)) // apply的作用

console.log(`1.this => ${this}`)

history.pushState的用处

以前做后台管理的时候,采用的是ajax+iframe,导致的问题是“刷新”就会回到首页,采用html5的history.pushState可以更好的完成,项目pajx就是封装了history和ajax的功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>
    <button id="btn">click</button>

    <a id="a" href="http://www.baidu.com" target="_self">baidu</a>

    <script>
        document.getElementById('btn').onclick = function() {
            var title = '新的页面'
            history.pushState(null, null, "line.html");

            document.title = title

            return false;
        }

        document.getElementById('a').onclick =  function () {
            console.log('...jump')

            // 可以阻止链接跳转
            return false
        }
    </script>
</body>
</html>

https://www.zhangxinxu.com/wordpress/2013/06/html5-history-api-pushstate-replacestate-ajax/

java8 Lambda&Stream Code

 /**
     * 获取年龄是22岁的员工
     */
    @Test
    public void testFilter() {
       list.stream()
               .filter(employee -> employee.getAge() == 22)
               .forEach(System.out::println);
    }

    /**
     *  获取所有员工的姓名,并用","连接
     */
    @Test
    public void testMap() {
        String str = list.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(","));
        System.out.println(str);
    }

    /**
     * 按照工资倒序排列,并获取第一个
     */
    @Test
    public void testSort() {
        Optional<Employee> optional = list.stream().sorted((e1, e2) -> {
            if (e1.getSlary() > e2.getSlary()) {
                return -1;
            } else if (e1.getSlary() == e2.getSlary()) {
                return 0;
            } else {
                return 1;
            }
        }).findFirst();

        System.out.println(optional.get());
    }

    /**
     * 最少工资
     */
    @Test
    public void testMin() {
        Double slary = list.stream()
                .map(Employee::getSlary)
                .min(Double::compareTo)
                .get();

        System.out.println(slary);
    }

    /**
     * 根据年龄进行分组
     */
    @Test
    public void testGroup() {
        Map<Integer, List<Employee>> map = list.stream().collect(Collectors.groupingBy(Employee::getAge));
        System.out.println(map);
    }

    /**
     * 工资大于5000的个数
     */
    @Test
    public void testCount() {
        Long count = list.stream().filter(employee -> employee.getSlary() > 8000)
                .count();

        System.out.println(count);
    }

    @Test
    public void testA() {

        BiPredicate<String, String> predicate2 = (s1, s2) -> s1.equals(s2);

        BiPredicate<String, String> predicate = String::equals;
        BiConsumer<List, String> bf = List::add;
        Function<Employee, String> f = Employee::getName;
        Supplier<String> s = String::new;

    }

    /**
     * 总薪水
     */
    @Test
    public void testStatistic() {
        DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Employee::getSlary));
        System.out.println(statistics.getSum());
    }

scss语法代码片段

/* Welcome to Compass.
 * In this file you should write your main styles. (or centralize your imports)
 * Import this file using the following HTML or equivalent:
 * <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */

@import "variable"; //导入变量文件

// 需要安装插件 gem install compass-normalize
// config.rb配置 require 'compass-normalize'
@import "normalize" ; 
//@import "compass/reset";
@import "compass/layout";

@include sticky-footer(54px);

/**
`commonProperty`先声明再使用
*/
@mixin commonProperty($w: 50%) {
    background: #fff;
    padding: 5px;
    width: $w;
    float: left;
}

.btn { // 编译「显示」到css中
    margin: 0;
}


%btn-hidden { // 编译「不显示」到css中
    text-align: center;
}

//----
.btn-primary {
    @extend .btn;
    @extend %btn-hidden;
    @include commonProperty();
    padding: 9px;
}

html, body {
    color: $color;

    font: { // 属性嵌套
        family: '黑体';
        size: 16px;
    }

    @at-root { // 保留层次关系,编译后到顶层
        .header {
            position: relative;
        }
    }
}

p {
    @include commonProperty(100%);

    background-image: image-url("a.png"); //属性中,直接调用函数
}

@debug append-url("hello.png"); 

/**
`makecText`先声明再使用
*/
@function makeText($selector) {
    @return $selector;
}


#{ makeText(".hello-world") } { //如果在选择器材中使用,#{functionName}
    color: red;
    font-size: 20px;
}

Apache + Let’s Encrypt配置HTTPS

申请通配符证书

# 下载 Certbot 客户端
$ wget https://dl.eff.org/certbot-auto

# 设为可执行权限
$ chmod a+x certbot-auto

# 移动的bin目录下
mv certbot-auto /usr/bin

部署apache

$ sudo certbot-auto --apache

根据命令行提示进行操作

  • 校验证书信息
openssl x509 -in  /etc/letsencrypt/live/xhope.top/cert.pem -noout -text
  • 证书和密钥保存在下列目录
tree /etc/letsencrypt/live/xhope.top/

修改配置文件

  • 查看apache配置文件路径
$ httpd -V
  • 编辑/conf.d/ssl.conf,使用证书。
LoadModule ssl_module modules/mod_ssl.so

Listen 443
<VirtualHost *:443>
    ServerName www.xhope.top
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/xhope.top/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/xhope.top/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/xhope.top/chain.pem
</VirtualHost>

  • 强制跳转到https,在网站的根目录下创建.htaccess文件
$ cd /var/www/html
$ vi .htaccess

编辑.htaccess

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

参考Apache 强制 HTTP 全部跳转到 HTTPS

  • 检查证书状态

https://www.ssllabs.com/ssltest/analyze.html?d=xhope.top

  • 其他工具检查

https://www.whynopadlock.com/

使用 crontab 让 lets encrypt 自动续期

Let’s Encrypt 证书只有 90 天的有效期,一旦我们忘记了就会失效了。所以建议使用 crontab 进行自动续期,让证书一直有效。

$ crontab -e

在编辑模式下添加

0 3 1 * * /usr/bin/certbot-auto renew 2>>/var/log/cert-renew.log >>/var/log/cert-renew.log

用 crontab -l 命令查看一下是否存在刚才添加的定时命令。如果存在的话,那么每月 1 日的凌晨 3 点就会执行一次所有域名的续期操作。不过有请求次数的限制所以别太频繁了。

$ crontab -l

https://www.vpsss.net/1328.html

参考网站: