Centos7

CentOS7安装Python3的方法CentOS7搭建L2TP服务端一键脚本CentOS7使用CertBot工具获取LetSencrypt泛域名HTTPS证书

Git

GIT删除仓库的历史提交记录脚本示例GIT进行代码量统计和贡献统计

HTTP

HTTP关于HEADER的详细解释HTTP协议对URI长度POST数据长度及COOKIE长度限制说明HTTP关于Code状态码的详细解释

JavaScript

JavaScript下的RSA对称加密DEMOJavaScript解析并遍历Excel示例代码JavaScript调用语音合成Speech Synthesis API使用ElementUI配合API数据快速渲染合并表格

Linux

Linux 信号说明列表说明Linux利用CronTab定时执行ThinkPHP命令行模式

MySQL

MySQL字符串截取MySQL腾讯云数据库导出备份到本地服务器导入MySQL设计与使用规范MySQL在5.7及以上版本中的ONLY_FULL_GROUP_BY问题处理方案

Nginx

Nginx反向代理NodeJS实现WSS协议Nginx反向代理中的Host参数传递遇到的坑Nginx配置HTTPS与HTTP2.0Nginx负载均衡的lnmp环境初始化脚本Nginx图片递归代理服务器DEMO

NodeJS

NodeJS一些冷门但实用的npm包NodeJS使用Request模块实现CURLNodeJS使用express模块无法收到phpCurl的值NodeJS使用jimp和qrcode-reader识别解析二维码NodeJS实现UDP数据报套接字通讯NodeJS实现Websocket聊天室NodeJS实现串口通讯简单例程NodeJS实现微信协议登录NodeJS实现超级方便的Git自动发布WebhookNodeJS控制台简单表格打印NodeJS转码amr到mp3NWJS配置文件

Other

C#串口通信扫码枪数据读取支付宝Schema协议列表默克尔树基础算法示例博客的升级历程

PHP

PHP下RSA对称加密超长字符串分段加密DEMOPHP下phpMyAdmin数据字典美化代码PHP下的RSA对称加解密-根证书自签与签发子证书PHP使用root权限执行系统命令和切换到www用户PHP使用独占文件指针实现阻塞少量并发PHP多进程同时处理任务示例DEMO代码PHP大文件视频上传WebUploaderPHP实现Web方式发起一个超时任务的处理请求PHP实现二叉查找树的简单代码实现PHP实现微博登录简单代码PHP微信JSSDK开发DEMOPHP的坑XML转JSONPHP简单实现QQ登录代码PHP获取URL HTTP_HOST和SERVER_NAMEPHP获取上周、本周、上月、本月、本季度、上季度时间方法PHP获取真实IP之IP代理-IP伪造-真实IPPHP解密微信小程序手机号简单DEMOPHP高精度计算常用代码

Python

Python3使用Pool进程池实现多进程并发Python3使用jieba分词并生成WordCloud词云图Python3使用request进行CURL操作Python3实现WebhookPython3使用Selenium进行自动化测试手册

Wechat

微信公众号php环境无法获取POST值微信公众号网页跳转避免出现导航栏的小技巧
博客的升级历程
手机阅读

扫描二维码阅读文章

V1.0 直接反向代理码云站点

比较喜欢在码云仓库的WIKI里边直接写MarkDown笔记,于是想到直接反向代理码云的WIKI预览页面,对其中一些样式进行替换和更改。

Nginx 反向代理配置文件

upstream blog_hamm_cn{
    server 212.64.62.174:443;
}
server{
    listen 80;
    server_name blog.hamm.cn;
    if ( $scheme = "http" ){
    	rewrite  (.*)  https://$http_host$1;
    }
    include enable-https.conf;
    location / {
        if ($request_uri ~* ^/(.*)\.html$){
            rewrite  ^/(.*)\.html$  /hamm/blog/wikis/pages?sort_id=$1 break;
        }
        if ($request_uri = /){
            rewrite  ^/(.*)$  /hamm/blog/wikis/pages break;
        }
        proxy_pass https://blog_hamm_cn;
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Host 'gitee.com';
    	proxy_set_header Connection "Upgrade";
    	proxy_set_header Accept-Encoding "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header User-Agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_set_header referer  'https://gitee.com/';
        sub_filter  "<div class='right'>" "<div style='position:fixed;right:20px;top:3px;color:#aaa;z-index:99999;font-size:14px;'><a href='https://hao.hamm.cn' target='_blank' style='color:#fff'>导航</a></div><div class='right' style='display:none;'>";
        sub_filter "<a href='/hamm/blog/wikis'>文档预览: Blog</a>" "<a href='/' style='font-size:24px;color:#fff;margin-left:20px;'>Hamm's Blog</a><span style='font-weight:normal;font-size:12px;color:#666;padding:0px 20px;'></span>";
        sub_filter "<i class='icon eye'></i>" "";
        sub_filter "<div id='doc-preview-header'>" "<div id='doc-preview-header' style='background-color:#333;'>";
        sub_filter "<a id='ex-all'>" "<a id='ex-all' style='display:none;'>";
        sub_filter "<div class='ztree-box'>" "<div class='ztree-box' style='margin-top:0px;padding-top:20px;'><script>setTimeout(function(){document.getElementById('ex-all').click();},1000);</script><script>var _hmt=_hmt||[];(function(){var hm=document.createElement('script');hm.src='https://hm.baidu.com/hm.js?7507c1a5bd29b0cc94228489ebd90b41';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(hm,s)})();</script>";
        sub_filter "文档预览 - 码云 Gitee.com" "Hamm's Blog";
        sub_filter "property='og:description'>" "property='nothing'><meta content='Hamm Blog' property='og:description'>";
        sub_filter "name='Description'>" "name='Description'><meta content='Hamm Blog' itemprop='description' name='Description'>";
        sub_filter " name='Keywords'>" " name='nothing'><meta content='Hamm,Blog' name='Keywords'><style>::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background-color:rgba(0,0,0,0);border-radius:5px}::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(0,0,0,0.1)}::-webkit-scrollbar-button{background-color:transparent}::-webkit-scrollbar-corner{background:transparent}</style>";
        sub_filter "<meta content='http://gitee.com/hamm/blog/wikis/pages?/&amp;sort_id=" "<meta content='http://blog.hamm.cn/";
        sub_filter "&amp;doc_id=487633' property='og:url'>" ".html' property='og:url'>";
        sub_filter 'url += "?sort_id=" + treeNode.sort_id' 'url +=  treeNode.sort_id+".html"';
        sub_filter '/hamm/blog/wikis/pages' '';
        sub_filter "url += '&doc_id=' + doc_id" "";
        sub_filter 'baseURL+"/show_page",' '"/hamm/blog/wikis/pages/show_page",';
        sub_filter_types text/css text/xml application/json application/javascript;
        sub_filter_once off;
    }
}

V2.0 更新为Docsify+Gitee WIKI

近期码云进行了静态资源的referer校验,本来对V1.0进行了小改,加上了另一个静态资源代理站,虽然基本实现,但高亮插件存在一些小问题。加上之前一直在犹豫Docsify和Gitee WIKI用哪个的问题(Docsify美观,适配手机端,可扩展强,但写Markdown依赖其他编辑器,而Gitee WIKI反代之后虽然自定义了样式,但在反向代理配置文件中写太多替换语句很不科学,于是升级了这个V2.0)

数据来源还是Gitee WIKI 但这里不再使用反向代理,而是直接写了个小爬虫:

<?php
if (empty($_GET['id'])) {
    die;
}
$id = strtolower(htmlspecialchars($_GET['id']));
switch ($id) {
    case  '_sidebar':
        $blog = [];
        $html = httpGetFull("https://gitee.com/hamm/blog/wikis/pages");
        if (preg_match("/<textarea id='wikis' style='display: none;'>(.*?)<\/textarea>/", $html, $matches)) {
            $blog = json_decode(htmlspecialchars_decode($matches[1]), true);
        } else {
            echo "# Blogs load error!";
            die;
        }
        $_blog = $blog;
        echo '- [Hello World](readme)';
        for ($i = 0; $i < count($blog); $i++) {
            $item = $blog[$i];
            if ($item['isParent']) {
                echo PHP_EOL . '- ' . $item['name'];
                for (
                    $j = 0;
                    $j < count($blog);
                    $j++
                ) {
                    $_item = $blog[$j];
                    if (!$_item['isParent']) {
                        if ($_item['pId'] === $item['id']) {
                            echo PHP_EOL . '    - [' . $_item['name'] . '](' . $_item['sort_id'] . ')';
                        }
                    }
                }
            }
        }
        break;
    case  'readme':
        echo file_get_contents('README.md');
        break;
    case  '_coverpage':
        echo file_get_contents('_coverpage.md');
        break;
    default:
        $url = "https://gitee.com/hamm/blog/wikis/pages/show_page?sort_id=" . $id . "&doc_id=487633";
        $html = httpGetFull($url, ['Accept' => '*/*']);
        $html = str_replace('\', '', $html);
        $html = stripcslashes($html);
        if (preg_match("/markdown-body'>(.*?)<link/", $html, $matches)) {
            print_r($matches[1]);
        } else {
            echo "# Blogs load error!";
            die;
        }
}
function  httpGetFull($url, $header = [], $cookies = "", $returnHeader = false, $isBackGround = false, $timeout = 0, $proxy = null)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_COOKIE, $cookies);
    if ($timeout) {
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    }
    if (!empty($proxy)) {
        curl_setopt($ch, CURLOPT_PROXY, $proxy['ip']);
        curl_setopt($ch, CURLOPT_PROXYPORT, $proxy['port']);
        curl_setopt($ch, CURLOPT_PROXYUSERPWD, "taras:taras-ss5");
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, $isBackGround ? 0 :
        1);
    curl_setopt($ch, CURLOPT_HEADER, $returnHeader ? 1 :
        0);
    $output = curl_exec($ch);
    if ($timeout) {
        if ($output === FALSE) {
            if (in_array(curl_errno($ch), [28])) {
                $output = 'TIMEOUT';
            } else {
                $output = 'ERROR';
            }
        }
    }
    curl_close($ch);
    return $output;
}

然而,Docsify是只对本地的markdown进行读取(虽然可以爬下来存一下,但实时性低),于是将Docsify的请求Rewrite到了第一步的爬虫上:

server{
    listen 80;
    server_name blog.hamm.cn;
    index index.php index.html;
    root  /home/wwwroot/blog/;
    if ( $scheme = "http" ){
        rewrite  (.*)  https://$http_host$1;
    }
    # 开启HTTPS服务
    include enable-https.conf;
    include enable-php.conf;
    include enable-cache.conf;
    
    location / {
        if ($request_uri ~* ^/(.*)\.md$){
            rewrite  ^/(.*)\.md$  /get.php?id=$1 last;
        }
    }
}

OK,V2.0版本的博客成功搞定!