首页
微语
统计
友链
留言
memos
圈子
图床
推荐
相册
网站监控
VPS监控
Search
1
为Typecho添加webp解析
38,062 阅读
2
实现typecho微信时光机功能的图文教程
31,854 阅读
3
emlog数据成功迁移到typecho
18,863 阅读
4
typecho 时光机单页 typecho-whisper
13,549 阅读
5
湖南移动5G特惠流量月包5元5GB/10元10GB
11,569 阅读
手机达人
免费资源
电脑网络
娱乐休闲
网站建设
威言威语
Typecho
Emlog
WordPress
服务器
主题
插件
排行榜    
登录
/
注册
Search
标签搜索
wordpress
发布
插件
免费
教程
typecho
EMlog
PHP
代码
CSS
华为
图片
代码修改
安装
评论
手机
诺基亚
微信
文章
智能
Chen'mo
累计撰写
1,265
篇文章
累计收到
367
条评论
首页
栏目
手机达人
免费资源
电脑网络
娱乐休闲
网站建设
威言威语
Typecho
Emlog
WordPress
服务器
主题
插件
页面
微语
统计
友链
留言
memos
推荐
相册
网站监控
VPS监控
搜索到
343
篇与
的结果
2021-02-24
自定义你的网站字体
最近有人卖字体的插件,其实弄个代码也很简单。下载自己喜欢的字体下载自己喜欢的字体,字体格式为.ttf,这里推荐一个字体网站:http://www.zhaozi.cn/s/all/ttf/转化字体格式将下载好的字体转换成.eot、 .woff、 .woff2三种格式,文件名可以是任意英文,没有特殊要求,可以根据自己的喜好命名(不要设置为中文就可以了)。这里推荐一个在线转化的网站:https://www.fontke.com/tool/convfont/上传字体至服务器将转换好的.eot、 .woff、 .woff2三种格式字体上传到自己网站任何位置,只要和后面的代码路径一致就可以了。插入CSS代码@font-face { font-family: "ziti"; src: url(https://你的文件路径/ziti.woff2) format("woff2"), url(https://你的文件路径/ziti.woff) format("woff"), url(https://你的文件路径/ziti.ttf) format("truetype"), url(https://你的文件路径/ziti.eot) format("embedded-opentype"), url(https://你的文件路径/ziti.svg) format("svg"); } body { font-family: ziti important; }以上代码的url链接为字体文件路径链接,可自行更改,"ziti"为字体名称,比如ziti.ttf,ziti.woff等等,在与字体文件名称相同的前提下可随意更改英文。放在style标签之内就可以了!如果大家闲麻烦可以直接把我的代码复制进去就可以了! <style type="text/css"> @font-face { font-family: "moonbridge"; src: url("https://ku.oioweb.cn/Resources/font/造字工房悦圆/moonbridge.woff2") format("woff2"), url("https://ku.oioweb.cn/Resources/font/造字工房悦圆/moonbridge.woff") format("woff"), url("https://ku.oioweb.cn/Resources/font/造字工房悦圆/moonbridge.ttf") format("truetype"), url("https://ku.oioweb.cn/Resources/font/造字工房悦圆/moonbridge.eot") format("embedded-opentype"), url("https://ku.oioweb.cn/Resources/font/造字工房悦圆/moonbridge.svg") format("svg"), url("https://ku.oioweb.cn/Resources/font/造字工房悦圆/moonbridge.otf") format("opentype"); font-weight: normal; font-style: normal; font-display: swap; } body{ font-family: 'moonbridge' } </style>顺便科普一下关于web中的字体有.woff, .eot, .svgTrueTypeWindows和Mac系统最常用的字体格式,其最大的特点就是它是由一种数学模式来进行定义的基于轮廓技术的字体,这使得它们比基于矢量的字体更容易处理,保证了屏幕与打印输出的一致性。同时,这类字体和矢量字体一样可以随意缩放、旋转而不必担心会出现锯齿。EOT-- Embedded Open Type (.eot)EOT是嵌入式字体,是微软开发的技术。允许OpenType字体用@font-face嵌入到网页并下载至浏览器渲染,存储在临时安装文件夹下。OpenType(.otf)OpenType是微软和Adobe共同开发的字体,微软的IE浏览器全部采用这种字体。致力于替代TrueType字体。WOFF--WebOpen Font Format (.woff)WOFF(Web开发字体格式)是一种专门为了Web而设计的字体格式标准,实际上是对于TrueType/OpenType等字体格式的封装,每个字体文件中含有字体以及针对字体的元数据(Metadata),字体文件被压缩,以便于网络传输。SVG(Scalable Vector Graphics) Fonts (.svg)SVG是由W3C制定的开放标准的图形格式。SVG字体就是使用SVG技术来呈现字体,还有一种gzip压缩格式的SVG字体。IE浏览器:EOTMozilla浏览器:OTF,TTFSafari浏览器:OTF,TTF,SVGOpera:OTF,TTF,SVGChrome浏览器:TTF,SVG
2021年02月24日
838 阅读
0 评论
0 点赞
2021-02-13
64M内存一键安装Typecho
前言说明OpenVZ的64M内存小鸡,不能增加swap的可以看看;如果您的服务器为KVM、能增加swap、内存大于256M建议直接关掉。此为一键安装部署,仅供交流使用,不保证稳定性。脚本特性小内存VPS 一键安装 Caddy + PHP7 + Sqlite3 环境 (支持VPS最小内存64M)一键绑定域名自动生成SSL证书开启https(ssl自动续期)、支持IPv6一键安装 typecho、wordpress、zblog、kodexplorer、laverna、一键整站备份支持系统 Centos 7 + Debian 8+(如果你内存实在太小,建议使用 mini 系统)项目地址https://github.com/dylanbai8/Onekey_Caddy_PHP7_Sqlite3配置说明这里以centos7.6 64位为例必须提前解析域名到该服务器。不然安装后会导致无法访问(签发SSL前提条件),支持IPv6(AAAA记录)如果本地网络不支持IPv6可以通过cloudflareCDN转换为IP4。在centos7里安装wget和下载caddy + php7 + Sqlite3yum install -y wget wget -N --no-check-certificate git.io/c.sh && chmod +x c.sh && bash c.sh安装好环境后,再使用以下命令安装所需要的程序,typecho直接复制运行第一条即可#一键安装typecho bash c.sh -t #一键安装wordpress bash c.sh -w #一键安装zblog bash c.sh -z #一键安装kodexplorer可道云 bash c.sh -k #一键安装laverna印象笔记 bash c.sh -l #一键整站备份(一键打包/www网站目录、含数据库) bash c.sh -a其他设置Caddy配置文件路径/etc/dylanbai8/caddy/Caddyfile以Typecho为例,其他程序同理vi /etc/dylanbai8/caddy/Caddyfile按下按键 i 在最后一个 } 后面添加#Typecho伪静态 rewrite { if {path} not_match ^\/admin to {path} {path}/ /index.php?{query} }再输入 ESC 然后输入 :wq 保存完毕然后重启caddysystemctl restart caddy其他命令及其目录启动:systemctl start caddy 停止:systemctl stop caddy 重启:systemctl restart caddy Caddy配置文件位置:/etc/dylanbai8 网站目录:/www严重声明此项目仅限于技术交流和探讨,在您测试完毕后必须在1秒钟内彻底删除项目副本。此项目为bash一键脚本,其中涉及到的任何软件版权和责任归原作者所有。
2021年02月13日
2,528 阅读
0 评论
0 点赞
2021-02-07
给网站挂上春节灯笼
要过年了,看大家的网站上都挂上了灯笼,我也挂一个。主题后台加个开关,方便随时关掉。代码:1.foot.pho里放如下代码: <div class="deng-box"> <div class="deng"> <div class="xian"></div> <div class="deng-a"> <div class="deng-b"><div class="deng-t">春节</div></div> </div> <div class="shui shui-a"><div class="shui-c"></div><div class="shui-b"></div></div> </div> </div> <div class="deng-box1"> <div class="deng"> <div class="xian"></div> <div class="deng-a"> <div class="deng-b"><div class="deng-t">快乐</div></div> </div> <div class="shui shui-a"><div class="shui-c"></div><div class="shui-b"></div></div> </div> </div>2.加上css代码:.deng-box { position: fixed; top: -30px; left: 220px; z-index: 9999; pointer-events: none; } .deng-box1 { position: fixed; top: -30px; right: 222px; z-index: 9999; pointer-events: none; } .deng-box1 .deng { position: relative; width: 120px; height: 90px; margin: 50px; background: #d8000f; background: rgba(216, 0, 15, 0.8); border-radius: 50% 50%; -webkit-transform-origin: 50% -100px; -webkit-animation: swing 5s infinite ease-in-out; box-shadow: -5px 5px 30px 4px rgba(252, 144, 61, 1); } .deng { position: relative; width: 120px; height: 90px; margin: 50px; background: #d8000f; background: rgba(216, 0, 15, 0.8); border-radius: 50% 50%; -webkit-transform-origin: 50% -100px; -webkit-animation: swing 3s infinite ease-in-out; box-shadow: -5px 5px 50px 4px rgba(250, 108, 0, 1); } .deng-a { width: 100px; height: 90px; background: #d8000f; background: rgba(216, 0, 15, 0.1); margin: 12px 8px 8px 10px; border-radius: 50% 50%; border: 2px solid #dc8f03; } .deng-b { width: 45px; height: 90px; background: #d8000f; background: rgba(216, 0, 15, 0.1); margin: -2px 8px 8px 26px; border-radius: 50% 50%; border: 2px solid #dc8f03; } .xian { position: absolute; top: -20px; left: 60px; width: 2px; height: 20px; background: #dc8f03; } .shui-a { position: relative; width: 5px; height: 20px; margin: -5px 0 0 59px; -webkit-animation: swing 4s infinite ease-in-out; -webkit-transform-origin: 50% -45px; background: #ffa500; border-radius: 0 0 5px 5px; } .shui-b { position: absolute; top: 14px; left: -2px; width: 10px; height: 10px; background: #dc8f03; border-radius: 50%; } .shui-c { position: absolute; top: 18px; left: -2px; width: 10px; height: 35px; background: #ffa500; border-radius: 0 0 0 5px; } .deng:before { position: absolute; top: -7px; left: 29px; height: 12px; width: 60px; content: " "; display: block; z-index: 999; border-radius: 5px 5px 0 0; border: solid 1px #dc8f03; background: #ffa500; background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03); } .deng:after { position: absolute; bottom: -7px; left: 10px; height: 12px; width: 60px; content: " "; display: block; margin-left: 20px; border-radius: 0 0 5px 5px; border: solid 1px #dc8f03; background: #ffa500; background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03); } .deng-t { font-family: 华文行楷,Arial,Lucida Grande,Tahoma,sans-serif; font-size: 1.5rem; color: #ffa500; font-weight: bold; line-height: 42px; text-align: center; width: 25px; margin: 0 auto; } .night .deng-t, .night .deng-box, .night .deng-box1 { background: transparent !important; } @-moz-keyframes swing { 0% { -moz-transform: rotate(-10deg) } 50% { -moz-transform: rotate(10deg) } 100% { -moz-transform: rotate(-10deg) } } @-webkit-keyframes swing { 0% { -webkit-transform: rotate(-10deg) } 50% { -webkit-transform: rotate(10deg) } 100% { -webkit-transform: rotate(-10deg) } }3.手机上不想显示,CSS里加上一这一句:@media (max-width: 678px){.deng-box{display:none;}} @media (max-width: 678px){.deng-box1{display:none;}}上面的代码来自网络:https://eebk.com/14.htmlJOE主题后面加个开关。head.php里加上<?php if ($this->options->chunjie === "on") : ?> <script src="https://cdn.jsdelivr.net/gh/lz1473/test@master/jscss/script/dl_2.js"></script> <?php endif; ?>这只有右边两个灯笼functions.php里加上控制代码我是放在返回顶部这个开关下面。参考它的代码修改的。 $chunjie = new Typecho_Widget_Helper_Form_Element_Select( 'chunjie', array('off' => '关闭(默认)', 'on' => '开启'), 'off', '是否开启春节灯笼', '介绍:开启后将在屏幕上方开启春节灯笼 <br />' ); $chunjie->setAttribute('class', 'j-setting-content j-setting-global'); $form->addInput($chunjie->multiMode());
2021年02月07日
1,976 阅读
0 评论
0 点赞
2021-02-06
jQuery实现网页刷新保持状态的黑暗模式
暗黑模式估计是今年最流行的网页配色了学习一点,进步一点。这个效果还是挺实用的,很多网页都有,但能找到的教程都不全面,或者是罗里吧嗦的长篇大论。能用最简单的方式实现,就绝不拖泥带水。直接上代码了,记录一下学习的成果。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <style> /* 基本白天的css样式 */ .box { width: 300px; height: 300px; background: orange; } /* 黑夜样式 */ html[dark='true'] body { background: #333; color:#bbb } html[dark='true'] .box { background: red; } #dark{cursor:pointer} </style> </head> <body> <!--darkmode start--> <div class="box"></div> <a id="dark" href="javascript:">黑</a> <!--darkmode end--> </body> </html> <script> if (localStorage.getItem('dark')) { $('html').attr('dark', true) $('#dark').text('白') } else { $('html').removeAttr('dark', true) $('#dark').text('黑') } $('#dark').on('click', function () { if ($('html').attr('dark')) { $('html').removeAttr('dark') localStorage.removeItem('dark') $('#dark').text('黑') } else { $('html').attr('dark', true) localStorage.setItem('dark', true) $('#dark').text('白') } }) </script>
2021年02月06日
1,311 阅读
0 评论
0 点赞
2021-01-24
Typecho如何获取文章图片数量?
该功能适合那些壁纸博客站,非常实用的一个小功能,显示文章内图片的数量,实现起来也非常的简单,有2种方法。方法一在主题function.php里添加代码如下(joe主题放在core/core.php里):function imgNum($content){ $output = preg_match_all('#<img(.*?) src="([^"]*/)?(([^"/]*)\.[^"]*)"(.*?)>#', $content,$s); $cnt = count( $s[1] ); return $cnt; }调用方法:<?php echo ''.imgNum($this->content).'' ; ?>适用于图片型主题.仅计算文章内使用的img标签数量.应用环境为:文章列表方法二在主题function.php里添加代码如下(joe主题放在core/core.php里):function imgNum($content){ $output = preg_match_all("/<img.<em>?src="(.</em>?)"<sup id="fnref-1"><a href="#fn-1" class="footnote-ref">1</a></sup>*>/i", $content,$matches); $cnt = count( $matches[1] ); return $cnt; }调用方法:<?php echo ''.imgNum($this->content).'' ; ?>
2021年01月24日
4,293 阅读
0 评论
0 点赞
2021-01-24
Typecho非插件实现首页隐藏单个或多个分类的文章
思路大概是:在模板中添加设置项->欲隐藏的分类ID(用英文逗号分割取多个)在index.php重新给文章列队(置顶文章同理)。最后通过分类与文章的关系(typecho文章分类是另外一个表)进行分类筛选。以下是index.php加入的代码: //首页隐藏某分类文章 if($this->options->cidId && $this->is('index')){ $this->row = []; $this->stack = []; $this->length = 0; $order = ''; //清空文章队列 $db = Typecho_Db::get(); $restPostSelect = $this->select('table.contents.cid', 'table.contents.title', 'table.contents.slug', 'table.contents.created', 'table.contents.authorId','table.contents.modified', 'table.contents.type', 'table.contents.status', 'table.contents.text', 'table.contents.commentsNum', 'table.contents.order','table.contents.template', 'table.contents.password', 'table.contents.allowComment', 'table.contents.allowPing', 'table.contents.allowFeed','table.contents.parent')->where('table.contents.type = ? and table.contents.status = ? and table.contents.created < ?', 'post','publish',time())->group('table.contents.cid'); $restPostSelect = $restPostSelect->join('table.relationships','table.relationships.cid = table.contents.cid','right')->join('table.metas','table.relationships.mid = table.metas.mid','right')->where('table.metas.type=?','category'); $cidId = explode(',', $this->options->cidId);//分割文本 $cidcount = 0; foreach($cidId as $i => $cid) { $cidcount = $cidcount + count($db->fetchAll($db->select('cid')->from('table.relationships')->where('mid = '.intval($cid)))); $restPostSelect->where('table.relationships.mid != '.intval($cid))->group('cid'); } $endSelect = $restPostSelect->order('table.contents.created', Typecho_Db::SORT_DESC); $rest_posts = $db->fetchAll($restPostSelect->order('table.contents.created', Typecho_Db::SORT_DESC)->page($this->_currentPage, $this->parameter->pageSize)); foreach($rest_posts as $rest_post) { $this->push($rest_post); } $this->setTotal($this->getTotal()-count($cidcount));//重新设置文章数 }在functions.php同样要加模板设置$cidId = new Typecho_Widget_Helper_Form_Element_Text('cidId', NULL, NULL, _t('首页列表不显示的分类ID'), _t('在这里填入欲隐藏的分类ID,使用半角逗号“,”填入多个,如:1,2,留空不显示')); $form->addInput($cidId);
2021年01月24日
4,570 阅读
1 评论
0 点赞
2021-01-22
EMLOG调用正文中图片(多图模式)的方法
代码说明(为修改代码的情况下,可根据自己的情况修改):使用本代码将实现当正文少于4张图片时候只调用一张图片;当少于8张图片时,调出4张;当大于8张图片时,调出8张图片代码效果:代码详情:<?php if(preg_match_all("/<img.*src=[\"'](.*)[\"']/Ui", $value['content'], $imgs) && !empty($imgs[1])){ $imgNum = count($imgs[1]); if($imgNum < 4) $n = 1; elseif($imgNum < 8) $n = 4; else $n = 8; for($i=0; $i < $n; $i++){ $img = $imgs[1][$i];echo "<img src='$img'>";} }else{ echo "<img src='图片地址'>";}//没有图片时显示 ?>下面代码自用,增加判断当只有一张图片时用不同css表达<?php if(preg_match_all("/<img.*src=[\"'](.*)[\"']/Ui", $value['content'], $imgs) && !empty($imgs[1])){ $imgNum = count($imgs[1]); if($imgNum < 5) $n = 1; elseif($imgNum < 10) $n = 5; else $n = 10; for($i=0; $i < $n; $i++){ if($n == 1){$img = $imgs[1][$i];echo "<p><img src='$img'></p>";} elseif($n > 1){$img = $imgs[1][$i];echo "<ul><li><img src='$img'><li></ul>";} } }else{ echo '<p><img src="图片地址" ></p>';}//没有图片时显示,为空则不显示 ?>代码说明:把上面代码直接放入log_list.php中你想要放入的位置即可,当然你也可以放入你的首页。
2021年01月22日
4,803 阅读
0 评论
0 点赞
2021-01-22
Typecho 文章按最后编辑排序
typecho默认的文章排序方式是按照文章发布的时间来排序的,有的时候我们可能写了某篇文章没写完,或者需要及时修改某篇文章已更新其内容的时效性,这时候可能我们就需要文章的排列是通过最后修改文章的时间来排序。偶然在jdeal大大的博客中发现了以下方法,修改后可根据最后编辑时间排序文章,下面是修改教程。打开根目录下/var/Widget/Archive.php文件,在源码1387-1393行处,可以看到如下的文章排序代码:/** 仅输出文章 */ $this->_countSql = clone $select; $select->order('table.contents.created', Typecho_Db::SORT_DESC) ->page($this->_currentPage, $this->parameter->pageSize); $this->query($select); }将上面代码中table.contents.created改成table.contents.modified就可以了
2021年01月22日
4,068 阅读
0 评论
0 点赞
2021-01-17
emlog文章列表获取附件(图片)数量方法
本方法实际获取的是文章附件的数量,而非只是图片的数量,如果你的文章含有文件附件,列表也会显示成图片数量。所以此方法最适合于文章图片特别多而且没有附件的博客。有强迫症必须显示图片实际数量的,请绕道。 emlog文章列表获取附件(图片)数量,方法过于简单,修改博客emlog模板文件步骤如下:1、在module.php文件里面加入以下代码:<?php //图片数量 function pic_num($attnum){ if ($attnum > 0) { echo '<span class="attnum" title="此文有 '.$attnum.' 张图片">',$attnum,'</span>'; } }?>2、在log_list.php文件里面进行以下操作:`找到 <?php echo $value['log_title']; ?> ,在其后 加上 <?php pic_num($value['attnum']); ?> 即可。`3、添加css样式到你的样式文件`.attnum{background: url(images/img.gif) no-repeat 5px center;padding-left: 20px} //图片可替换自己的图片,字体大小自己调节`
2021年01月17日
5,607 阅读
0 评论
0 点赞
2021-01-17
实现emlog网站信息统计的代码
有时候想在网页中向访客展示emlog博客的文章数量、评论数量、运行时间等信息,但emlog后台侧边栏没有提供相关的模块,因此需要博主自主添加博客统计信息代码。下面是博客吧整理的emlog网站信息统计代码,已在emlog 5.3.x上测试可用。 调用代码: 方法一:官方缓存类统计代码。优点:加载速度快;缺点:可能信息更新不及时。把以下代码添加到当前使用的主题模板文件中,如side.php文件:<?php $sta_cache = Cache::getInstance()->readCache('sta'); /*必须添加*/ ?> <ul> <li>文章总数:<?php echo $sta_cache['lognum']; ?> 篇</li> <li>评论总数:<?php echo $sta_cache['comnum_all']; ?> 条</li> <li>闲言碎语:<?php echo $sta_cache['twnum']; ?>条</li> <li>网站运行:<?php echo floor((time()-strtotime(20160423))/86400); ?> 天</li> </ul>附:$sta_cache[‘参数’]中的参数可选如下:lognum游客可见日志总数draftnum草稿,也就是隐藏文件数量comnum未隐藏的评论数量comnum_all所有评论数量hidecomnum被隐藏的评论数量twnum微语数量checknum未审核的文章数量方法二:自编函数,通过SQL语句查询相关数据。缺点:加载速度较缓存类慢;优点:实时显示把下面的代码添加到主题的module.php文件中:<?php //统计文章总数 function count_log_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "blog WHERE type = 'blog'"); return $data['total']; } //置顶文章数 function count_log_top(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "blog WHERE top = 'y' or sortop = 'y' AND type = 'blog'"); return $data['total']; } //隐藏文章数 function count_log_hide(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "blog WHERE hide = 'y' AND type = 'blog'"); return $data['total']; } //未审核文章数 function count_log_check(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "blog WHERE checked = 'n' AND type = 'blog'"); return $data['total']; } //加密文章数 function count_log_pass(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "blog WHERE password !='' AND type = 'blog'"); return $data['total']; } //统计页面总数 function count_page_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "blog WHERE type = 'page'"); return $data['total']; } //统计评论总数 function count_com_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "comment"); return $data['total']; } //统计友链总数 function count_link_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "link"); return $data['total']; } //统计微语评论总数 function count_treply_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "reply"); return $data['total']; } //统计分类总数 function count_sort_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "sort"); return $data['total']; } //统计子分类数 function count_sort_mod(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "sort WHERE pid != 0"); return $data['total']; } //统计标签总数 function count_tag_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "tag"); return $data['total']; } //统计微语总数 function count_tw_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "twitter"); return $data['total']; } //统计用户总数 function count_user_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "user"); return $data['total']; } //统计管理员总数 function count_user_admin(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "user WHERE role = 'admin'"); return $data['total']; } //统计作者总数 function count_user_writer(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "user WHERE role = 'writer'"); return $data['total']; } //统计附件总数 function count_att_all(){ $db = MySql::getInstance(); $data = $db->once_fetch_array("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "attachment"); return $data['total']; } //最后发表文章时间 function last_post_log(){ $db = MySql::getInstance(); $sql = "SELECT * FROM " . DB_PREFIX . "blog WHERE type='blog' ORDER BY date DESC LIMIT 0,1"; $res = $db->query($sql); $row = $db->fetch_array($res); $date = date('Y-n-j H:i',$row['date']); return $date; }; ?> 调用代码:<ul> <li>文章总数:<?php echo count_log_all();?></li> <li>置顶文章:<?php echo count_log_top();?></li> <li>隐藏文章:<?php echo count_log_hide();?></li> <li>待审文章:<?php echo count_log_check();?></li> <li>加密文章:<?php echo count_log_pass();?></li> <li>页面总数:<?php echo count_page_all();?></li> <li>评论总数:<?php echo count_com_all();?></li> <li>友链总数:<?php echo count_link_all();?></li> <li>微语评论:<?php echo count_treply_all();?></li> <li>分类总数:<?php echo count_sort_all();?></li> <li>子分类数:<?php echo count_sort_mod();?></li> <li>标签总数:<?php echo count_tag_all();?></li> <li>微语总数:<?php echo count_tw_all();?></li> <li>用户总数:<?php echo count_user_all();?></li> <li>管理员数:<?php echo count_user_admin();?></li> <li>作者总数:<?php echo count_user_writer();?></li> <li>附件总数:<?php echo count_att_all();?></li> <li>最后更新:<?php echo last_post_log();?></li> </ul>来自:https://pjax.cn/em_tongji.html
2021年01月17日
3,675 阅读
0 评论
0 点赞
2021-01-16
Emlog通过邮箱判断获得Gravatar或者QQ的头像
有时候有些访客可能并没有 Gravatar 头像,那么很多人可能填写的都是QQ邮箱,于是有了下面的代码把下面的代码放到 Emlog 的 module.php 文件里//获取Gravatar头像 QQ邮箱取用qq头像 function ea_getGravatar($email, $s = 96, $d = 'mp', $r = 'g', $img = false, $atts = array()){ preg_match_all('/((\d)*)@qq.com/', $email, $vai); if (empty($vai['1']['0'])) { $url = 'https://secure.gravatar.com/avatar/'; $url .= md5(strtolower(trim($email))); $url .= "?s=$s&d=$d&r=$r"; if ($img) { $url = '<img src="' . $url . '"'; foreach ($atts as $key => $val) $url .= ' ' . $key . '="' . $val . '"'; $url .= ' />'; } }else{ $url = 'https://q2.qlogo.cn/headimg_dl?dst_uin='.$vai['1']['0'].'&spec=100'; } return $url; }调用方法:<?php echo ea_getGravatar($value['mail']);?>来源:https://mengx.io/post/8
2021年01月16日
2,530 阅读
0 评论
0 点赞
2021-01-16
Emlog日期格式化代码
很多时候常规的时间日期格式已经看腻了,是时候来点别的了。比如说发布几秒钟/几分钟/几小时,那么就喜欢处理下我们的时间戳了。不多说废话,直接上代码,把下面代码放到主题的module.php文件中<?php //日期格式化 function ea_timeago($ptime) { $ptime = strtotime($ptime); $etime = time() - $ptime; if ($etime < 1) return '刚刚'; $interval = array ( 12 * 30 * 24 * 60 * 60 => date('Y-m-d', $ptime), 30 * 24 * 60 * 60 => date('m-d', $ptime), 7 * 24 * 60 * 60 => date('m-d', $ptime), 24 * 60 * 60 => '天前', 60 * 60 => '小时前', 60 => '分钟前', 1 => '秒前' ); foreach ($interval as $secs => $str) { if ($etime < 7 * 24 * 60 * 60){ $d = $etime / $secs; if ($d >= 1) { $r = round($d); return $r . $str; } } else { return $str; } }; }?>在 list_log.php 列表页调用<?php echo ea_timeago(timeago(gmdate('Y-m-d', $value['date']))); ?>在 echo_log.php 文章阅读页调用<?php echo ea_timeago(gmdate('Y-n-j', $date)); ?>
2021年01月16日
2,335 阅读
0 评论
0 点赞
2020-12-13
Chevereto 配合 Picgo 打造个人相册 / 图床解决方案
Chevereto 是一款很好用图床工具,可以实现一键上传、一键 Markdown 引用等功能,最近发现还可以和 Picgo 配合起来使用,打造更加方便实用个人图床。Picgo 是一个用于快速上传图片并获取图片 URL 链接的工具,支持全桌面客户端,应该是目前本人用过最好用的图床链接工具了。今天主要介绍如何使用 Chevereto + Picgo 实现一键上传图片到特定用户、相册中。至于 Chevereto 的安装和 Picgo 的安装,网上教程很多,不再赘述,在这里给出一些参考链接,自取:Chevereto 官网:https://chevereto.com/Chevereto DEMO:https://demo.chevereto.com/Picgo 官网:https://molunerfinn.com/PicGo/Chevereto 安装教程:https://www.moerats.com/archives/390/在 Picgo 上实现 api 上传的工具很多,如 chevereto 、 web-uploader 等。但 Chevereto 默认的 api 会将图片上传到访客目录下,不支持自定义。因此在这里通过修改源代码的方式实现上传图片到特定用户的特定目录下。在 Chevereto 安装目录下找到这个文件:app/routes/overrides/route.api.php注:若不存在,请从上一级目录中拷贝一个 route.api.php 至该目录下。按照如下方式修改该文件:- $uploaded_id = CHV\Image::uploadToWebsite($source);+ // $uploaded_id = CHV\Image::uploadToWebsite($source); + $uploaded_id = CHV\Image::uploadToWebsite($source, 'testuser', array('album_id'=>3));其中, testuser 和后面的相册 id ,为最终 api 上传图片所在用户的相册下,您可以根据自己的需求设定。之后重载 PHP 即可。
2020年12月13日
1,752 阅读
0 评论
0 点赞
2020-08-30
Typecho 评论中嵌入图片
有时发表评论需要添加图片,Typecho本身支持在评论中开启嵌入图片,但是还需要手工补全<img src= />来实现图片插入,比较麻烦。其实可以学习 v2ex 自动把图片后缀的文件自动转换为图片链接。首先在functions.php中添加转换函数function parseComment($comment) { $size = auto; $comment = preg_replace(array('#(http://([^\s]*)\.(jpg|gif|png|JPG|GIF|PNG))#', '#(https://([^\s]*)\.(jpg|gif|png|JPG|GIF|PNG))#'), '<img src="$1" alt="评论" style="width:' . $size . '; height:' . $size . '" />', $comment); return $comment; }如果你的主题有评论自定义,那么请找到 threadedComments 函数,在里头把$comments->content();修改为echo pareseComment($comments->content);没有的话你还要参照Typecho官方文档自定义评论才行。来源:https://xiamp.net/archives/embed-pictures-in-typecho-comments.html
2020年08月30日
4,969 阅读
0 评论
0 点赞
2020-08-30
Typecho 统计最近更新文章数量
我最近又换主题了,每年不换十几个主题,心里总觉得不痛快,小灯泡的主题很好,我想改,但是一更新,我又麻烦了,所以就干脆自己搞吧。废话说了这么多,这个主题有个最近更新文章数量的统计,见下图:那么怎么实现呢?代码如下://统计多少天内发布的文章数量 function getNumPosts($days){ $db = Typecho_Db::get(); $st_days= time()-$days*24*60*60; $result = $db->fetchAll($db->select()->from('table.contents') ->where('status = ?','publish') ->where('type = ?', 'post') ->where('modified >= ?', $st_days) //统计时间 ); $total_posts = count($result); return $total_posts; }怎么调用呢?在你需要显示文章数的地方插入下面代码:<?php echo getNumPosts(1); ?>括号里面的1,表示1天内,可以自己根据需要修改天数。来源:https://pangsuan.com/p/typecho-posts-count.html
2020年08月30日
4,362 阅读
0 评论
0 点赞
2020-07-26
文章加密测试, 密码cmsblog
Emlog 程序的钩子远不如 WordPress 这么丰富,因此这一美化只能通过直接修改 Emlog 代码来实现。具体的位置在 include/model/log_model.php 文件末尾的 authPassword 函数。将原来的代码: if ($pwd !== addslashes($logPwd)) { echo <<<EOT <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>emlog message</title> <style type="text/css"> <!-- body{background-color:#F7F7F7;font-family: Arial;font-size: 12px;line-height:150%;} .main{background-color:#FFFFFF;margin-top:20px;font-size: 12px;color: #666666;width:580px;margin:10px 200px;padding:10px;list-style:none;border:#DFDFDF 1px solid;} --> </style> </head> <body> <div class="main"> <form action="" method="post"> 请输入该文章的访问密码<br> <input type="password" name="logpwd" /><input type="submit" value="进入.." /> <br /><br /><a href="$url">«返回首页</a> </form> </div> </body> </html> EOT; if ($cookiePwd) { setcookie('em_logpwd_' . $logid, ' ', time() - 31536000); }修改为: if ($pwd !== addslashes($logPwd)) { ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="renderer" content="webkit"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>该文章已被加密</title> </head> <body> <div class="main"> <img class="alert" alt="文章已被加密" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIoAAACACAMAAADjwgEwAAAAOVBMVEUAAAD5dBr7dRj4dBn/cBD5cxr4cxn6chj7dBj/cBj5cxr5dBn6cxn4dBn5cxr6dRX5cxr5cxr5dBoQJfbPAAAAEnRSTlMAgD/AEPDgYEAgoLCQcFAw0J/MNdW8AAADg0lEQVR42s3b7W7iMBSEYWftxA75At//xW7VZRWnQ3WkvOKE+VmJMtjxg8Ek4Iy5e8zdmsLFSXmoz8QSrsw61CZxDJdlrsf0OVyUR5WALrDJh3SZ68uswT1rfZ3e/dpNff0lMTjnVr/yEVO01SZdWae6Z/CFNzYXxxa+kttqwTHl2ORHl95zWBrvl/BMM0e34JZ8XC+6phwWtD7ptv95uWBBdzIVMm0luGTshVYB+B5ccvt12Ubnt8Xt91Vb3JyzX/rk5Jy+cr2M3Jyzl8nMnOO6Bewc103TMee4btw5rpsmA+e4bm7O2boh57huS9twyaODc7Zu43fBR3J1bni1q0/Pv0bgHNNNl3cGzgHdyouhmqBzXLf9SZ2c01HXKsA5pptWcXJOV6hWAc5R3bQKcI7qplUcnLs3uhlV1Ln5bboZVd7rXGqdMKuoQ9ObdDOqAOeAbkYVY0fOdTOqAOeAblLFEOAdutlVbOe4bmYV4BzQzahiOId104DPrVw3uwp3zv5fdhXgHNDNqAKcs3Sbw4kqhnNAN7vK25yLhlFGFcM5pJtdBTtn65ZPVDGcY7rZVbhzpgmgitgEdQNV5DUx3UAV5pxebaCKOMd0A1WYcyoTqKJWIt1AFeSczi6rou+rQDdQBTmnEoAqzLn9cfvjYBXdmQLdQBXgnOrGq+j7PNANVAHOiW6gCnBO2idQBTunuvEqtnPoxE2rgJXJdNMqyCt8OqsnH8A5NoZ6HgScoyf5+ykZ+raGr7f97PCWwD4I6iYnquCbPa4b/0aA6OZwgo9/NwV2IEC3950YeP7GTp1DuhkBzpkDx2M7x3XTAOfMRWZn7OJwn5YETjCQbjqtw8qc47o95GHAOaTbUptswDmkm/6aPwLnsG65HpKQc/rqtvP3fRTgHNUt1kM67tx49u6RqR6SgXNIt30097mlzpXT5G+1zQD2c3zvFmV+kHM6aedgieDBz2GZyN5t2+87TGQ/131PGdu7pa7/Hs/M9nPDD2i3cCqllA3s5/bnjqKbY4bDDLXFQOiwxJaGe/BP2gcihCLQuiZKlV1f58zNDmr9lNtLSyg+C8jeKrSXbX/pCqqHxdyvwTO6j53qnvu8/nFLfgz1uGXJ9SMy/sP3A3J7fhq7Pv34f21fnkUWt3eUtDTVSzPL1u6SKGfjrV6TvtM98bhccMlMOYWXSWXpHJNLaPMXZ8oyOMxlLIsAAAAASUVORK5CYII="> <form action="" method="post" class="mk-side-form"> <h2 class="pw-tip">该文章已被加密</h2> <input type="password" name="logpwd" placeholder="请输入访问密码查看" required><button type="submit">提交</button> <?php if($postPwd): ?> <p id="pw-error">Oops!密码不对哦~</p> <script>setTimeout(function() {document.getElementById("pw-error").style.display = "none"}, 2000);</script> <?php endif; ?> </form> <a href="<?php echo $url; ?>" class="return-home" title="点击回到网站首页">- 返回首页 - </a> </div> <style type="text/css"> *{font-family:"Microsoft Yahei",微软雅黑,"Helvetica Neue",Helvetica,"Hiragino Sans GB","WenQuanYi Micro Hei",sans-serif;box-sizing:border-box;margin:0px;padding:0px;font-size:14px;-webkit-transition:.2s;-moz-transition:.2s;-ms-transition:.2s;-o-transition:.2s;transition:.2s} html,body{width:100%;height:100%} body{background-color:#F4F6F9;color:#768093} input,button{font-size:1em;border-radius:3px;-webkit-appearance:none} input{width:100%;padding:5px;box-sizing:border-box;border:1px solid #e5e9ef;background-color:#f4f5f7;resize:vertical} input:focus{background-color:#fff;outline:none} button{border:0;background:#6abd09;color:#fff;cursor:pointer;opacity:1;user-select:none} button:hover,button:focus{opacity:.9} button:active{opacity:1} .main{width:100%;max-width:500px;height:300px;padding:30px;background-color:#fff;border-radius:2px;box-shadow:0 10px 60px 0 rgba(29,29,31,0.09);transition:all .12s ease-out;position:absolute;left:0;top:0;bottom:0;right:0;margin:auto;text-align:center} .alert{width:80px} .mk-side-form{margin-bottom:28px} .mk-side-form input{float:left;padding:2px 10px;width:77%;height:37px;border:1px solid #ebebeb;border-right-color:transparent;border-radius:2px 0 0 2px;line-height:37px} .mk-side-form button{position:relative;overflow:visible;width:23%;height:37px;border-radius:0 2px 2px 0;text-transform:uppercase} .pw-tip{font-weight:normal;font-size:26px;text-align:center;margin:25px auto} #pw-error {color: red;margin-top: 15px;margin-bottom: -20px;} .return-home{text-decoration:none;color:#b1b1b1;font-size:16px} .return-home:hover{color:#1E9FFF;letter-spacing:5px} </style> </body> </html> <?php if ($cookiePwd) { setcookie('em_logpwd_' . $logid, ' ', time() - 31536000); }文章来源:https://mkblog.cn/1634/演示网址:
2020年07月26日
2,703 阅读
0 评论
0 点赞
2020-06-11
简单CSS3技巧实现的Logo动画
之前不少人提过说要实现像阿里百秀Logo那样的动画效果,为了满足广大用户的需求,这里就简单做个演示。东西相对较简单,所以不要认为你搞不定它。下面是案例代码<style>.imlogo{ display: block; width: 160px; height: 80px; background: #FF5E52 url(https://themebetter.com/uploads/2015/01/logo2.png) center 22px no-repeat; -webkit-transition: background-position linear .2s; -moz-transition: background-position linear .2s; transition: background-position linear .2s;}.imlogo:hover{ background-position: center -48px;} </style> <a class="imlogo" href="#"></a>其实你只需要改变其中的图片地址、Logo区域大小(160px和80px)背景图的坐标(22px和-48px),你就能实现自己的动画了,如果你很懒,那就做个119*100px的logo即可,像下面这样的一张图(背景做成透明的,png格式,即可实现代码改变颜色)。在主题的style.css最后加上,再做个原来Logo高度2倍的图先替换,然后更改其中的-48为你的位置即可,不会计算的话直接多试几个就能知道哪个合适了。本文属原创,转载请注明原文:https://themebetter.com/css3-logo.html
2020年06月11日
1,982 阅读
0 评论
0 点赞
2020-06-11
优雅的破解网页内容禁止选中以及复制的问题
我们在优雅的使用浏览器查询我们需要的资料的时候,难免会遇到一些网站有无法复制内容的问题,这些网站一般是通过JS的方式实现禁止内容复制的,所以我们可以简单的使用浏览器控制台命令来从新打开内容复制。首先,我们需要分析一下如何实现禁止复制粘贴。实现禁止复制粘贴// 禁止右键菜单 document.oncontextmenu = function(){ return false; }; // 禁止文字选择 document.onselectstart = function(){ return false; }; // 禁止复制 document.oncopy = function(){ return false; }; // 禁止剪切 document.oncut = function(){ return false; }; // 禁止粘贴 document.onpaste = function(){ return false; };解决禁止复制粘贴既然我们知道了实现的方式,那我们就可以直接按下F12打开浏览器的控制台,然后点击控制台输入以下代码即可// 开启右键菜单 document.oncontextmenu = function(){ return true; }; // 开启文字选择 document.onselectstart = function(){ return true; }; // 开启复制 document.oncopy = function(){ return true; }; // 开启剪切 document.oncut = function(){ return true; }; // 开启粘贴 document.onpaste = function(){ return true; };文章来源:https://eas1.cn/201.html
2020年06月11日
1,045 阅读
0 评论
0 点赞
2020-06-07
Typecho 评论中嵌入图片
有时发表评论需要添加图片,Typecho本身支持在评论中开启嵌入图片,但是还需要手工补全<img src= />来实现图片插入,比较麻烦。其实可以学习 v2ex 自动把图片后缀的文件自动转换为图片链接。首先在functions.php中添加转换函数function parseComment($comment) { $size = auto; $comment = preg_replace(array('#(http://([^\s]*)\.(jpg|gif|png|JPG|GIF|PNG))#', '#(https://([^\s]*)\.(jpg|gif|png|JPG|GIF|PNG))#'), '<img src="$1" alt="评论" style="width:' . $size . '; height:' . $size . '" />', $comment); return $comment; }如果你的主题有评论自定义,那么请找到 threadedComments 函数,在里头把$comments->content();修改为echo pareseComment($comments->content);没有的话你还要参照Typecho官方文档自定义评论才行。
2020年06月07日
5,462 阅读
1 评论
0 点赞
2020-05-24
浏览器野史 —— UserAgent 列传【转载】
某天,我做一个小项目,需要判断一下浏览器类型。简单的呀。控制台敲下:navigator.userAgent浏览器回应:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36天,这串是啥?你怎么连话都说不清楚?我对 UserAgent 并不陌生,但明明一个单词就可以说清楚的事情,却是这么掏心掏肺的回答。怪可怜的,一定有冤情。后来我查阅了很多资料,发现历史非常的精彩。大事年表1990年: Nexus ( WorldWideWeb )诞生1993年1月23日:Mosaic 诞生1994年12月:Netscape ( Mozilla )诞生1995年4月:Opera 诞生1995年8月16日:Internet Explorer 诞生2002年9月23日:Firefox 诞生2003年1月7日:Safari 诞生2008年9月2日:Chrome 诞生一、盘古开天地很久很久之前,上古大神 Berners-Lee 发明了 WorldWideWeb ,即万维网。同时,李大神也发明了第一款浏览器。真是具有跨时代意义的工具呀,好伟大呀,人们在想,叫什么好呢?但大神就是大神,大神内心的想法又岂是尔等凡人能够肆意揣摩?万万没想到,李大神说,我这浏览器,也叫 WorldWideWeb !不行么?行行行。虽然李大神起名字这么拽,但他后来发觉,还是得赋予一点承上启下的历史意义,就改名成“Nexus”。值得注意的是,这浏览器,居然是可以兼容 Unix 跟 Microsoft DOS 的。它在当时流行的各种电脑上跑得飞起,应用也越来越广,被称为“杀手级应用”。杀手级…你们看互联网一开始就是这么的腥风血雨。但这个浏览器,还不支持图片的显示,这是出现 UserAgent 的导火索。二、唐尧虞舜93 年,伊利诺大学的 NCSA 组织认为,浏览器无图无真相,这不好。因而他们发明了第一款可显示图片的浏览器。真是具有跨时代意义的工具呀,好伟大呀,人们在想,叫什么好呢?但大神就是大神,大神就是连起名字都让你惊心动魄。NCSA 组织说,它能显示图片,偏偏我们就要叫它“马赛克( Mosaic )”!不行么?行行行。但有人就问了,Nexus 不显示图片,Mosaic 能显示,你们让 html 提供者怎么写代码?你们是不是想逼死选择困难症患者?有没有考虑过天秤座的感受?因而 UserAgent 就诞生了。Mosaic 将自己标志为 NCSA_Mosaic/2.0 (Windows 3.1) ,大家该怎么写代码就怎么写,但请求会带上这个信息,服务器就知道该不该返回能显示图片的 html 。UserAgent 君,出生时跟我们设想的一样简单,仅仅标明了自己是什么浏览器,在什么系统运行,以及各自的版本号。新旧浏览器们像彬彬有礼的君王,商议和让位是为了更好的繁荣。但风雨欲来。三、楚汉争霸像刘邦一样,走出来一个搅局的小流氓。当然他还是很有志向的,他的目标,就是战胜霸主 Mosaic。后来,他还真的做到了。如今,所有现代浏览器的 UserAgent 里都有它的标志,就像汉朝之后,我们都称为“汉”人。一群很有天赋的程序员,一起缔造了它的辉煌。真是具有跨时代意义的工具呀,好伟大呀,人们在想,它叫什么呢?但大神就是大神,大神就是让你永远也猜不到他们想了个什么名字。大神们说,叫 Mozilla,不行么?行。但什么意思呢?含义有二。其一,哥斯拉( Godzilla )谐音,诚然是一头野心勃勃的怪兽;其二,”Mosaic Killa”之意, Killa 是俚语中 Killer 的拼法,即“马赛克的终结者”,赤裸裸的挑战。惊呆了的 Mosaic 小心翼翼的念着 Mozilla 这发音:“Mo…摸咋了?”勃然大怒,“摸你妹!”鉴于 Mosaic 当时的权势,Mozilla 改名成 Netscape Navigator (网景航海家)。小怪兽突然变成有点文艺小清新的名字,郁闷得很,但内心的血液沸腾着。虽然叫大名叫网景,但它把 UserAgent 偷偷设置成 Mozilla/1.0 (Win3.1) 。还是摸咋了?咬我?四、宋元之战很快, NetScape 战胜了 Mosaic ,成为了新的霸主,因为其更优的展示。NetScape 最先支持了 html 框架显示,就是简单的 table 布局,内外边距之类,仅仅这点就将 Mosaic 抛诸身后。区别这两个浏览器,还是用的 UserAgent 。如果是 UserAgent 里含有“Mozilla”字样,那就发送支持框架的页面,否则,就发送不含框架的页面。NetScape 帝国日益庞大,歌舞升平,一切风平浪静,直到微软的铁骑挥军南下。微软发布了一款跟系统强绑定的浏览器,真是具有跨时代意义的工具呀,好伟大呀,人们在想,它叫什么呢?不用想了,就是 IE 。这命名也相当简单粗暴, Internet Explorer ,直接把这工具的用途拍在你脸上。连说明书都可以免了。IE也是支持 html 标准框架的,但由于前面的历史原因,人们只会给 UserAgent 里含有“Mozilla”字样的浏览器发送含框架的页面。但这点小事能难倒我大微软? IE 呵呵一笑,把自己的 UserAgent 改成 Mozilla/1.22 (compatible; MSIE 2.0; Windows 95) 。看,我这里也有 “Mozilla” 字样,也能收到含框架的页面了!当然,这个小流氓行为,跟后来把 IE 和 Windows 捆绑一起销售的大流氓行为比起来,根本不为足道。后面的故事我们也知道了, IE 把 NetScape 干掉了。但它的身体上,却永远的烙上了“Mozilla”的印记。五、康乾盛世看过奥特曼的都知道,怪兽被打败了会再回来。别忘了 NetScape 曾拥有一批大神们,失败后,他们围绕着浏览器排版引擎 Gecko (壁虎)成立了非正式组织 Mozilla 。小怪兽再次出发。大神们发明了另一款优秀的浏览器,它在插件拓展和开发调试领域做出的贡献,绝对可以载入互联网历史。真是具有跨时代意义的工具呀,好伟大呀,人们在想,它叫什么呢?但大神就是大神,大神就是即使你知道了 Mozilla 的命名都是野兽,却还是猜不到是什么。Mozilla 说,我们浴火重生,叫 Phoenix (凤凰)!不行么?真不行。刚推出就被人告了,原来已经有一家公司叫做“凤凰科技”。Mozilla 瀑布汗,改名叫 Firebird (火鸟)!还不行么?我们得原谅一下他们的取名,虽然现在看来满满的山寨感,可放在那个时代, Firebird 这名字很炫酷。就像你当初的 QQ 昵称叫赤炎天使感觉依然良好一样。但是,他们发现,业内有个数据库系统,也叫的 Firebird …泪流满面的 Mozilla 感慨重生好难呀。最后才决定叫Firefox (火狐)。基于 Gecko 引擎的 Firefox 非常优秀,为了告诉大家,我使用了这个引擎,它标志自己的 UserAgent 为 Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0 。这时候的 UserAgent ,虽然长了点,但它并不混乱,准确的标明了系统,排版引擎,浏览器名称等信息。虽然 IE 这时已经占有了很大的市场份额,但基本停步不前;而 Mozilla 经过一段时间的修生养息,Firefox 在业内广受好评,得到了快速的发展。时值 2003 年, web2.0 的浪潮前夕,浏览器的发展达到了空前的盛世。然而所谓否极泰来,盛极则衰。涅槃的 Firefox 迎来盛世,却又恰恰由于盛世,决定了 UserAgent 纠结的命运。六、师夷长技前面说到,微软靠 Windows 系统捆绑IE销售。而 Windows 自然也有它的对手,Linux 。一个技术快速发展的时代,系统的世界里也是战火纷飞。 Linux 系统自从有了可视化界面,也需要浏览器呀。桌面系统 KDE 的缔造者们就发明了一个。真是具有跨时代意义的工具呀,好伟大呀,人们在想,它叫什么呢?但大神就是大神,大神就是讲究先从文字上占据压垮你的气势。先有 Navigator 航海家,再有 Explorer 探索者,咱就叫 Konqueror ( Conqueror 的变体)征服者吧。行行行。我已懒得理这帮大神…可是,问题来了。 Konqueror 使用 KHTML 排版引擎,即使它们认为自己跟 Gecko 引擎一样优秀,但用户不买单。你 UserAgent 里没有“Gecko”字样,我就不给你经过优良排版的 html。结果, Konqueror 思来想去,做了一个艰难但很萌的决定,把 UserAgent 写成 Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko) …这就是现代浏览器里 like Gecko 这一萌词的由来。就这样,伟大的排版引擎 KHTML 为了获得更好的资源,师夷长技。这并没什么不好,却造成了 UserAgent 的越发混乱。KHTML 与 Gecko 这一对,永远卿卿我我比翼双飞在 UserAgent 里面了。那个满含深意的“like”,有人觉得翻译成“像”,但也有人觉得应该是“喜欢”…七、世界大战首先是 IE 冷静下来了,他觉得,你们不带这么玩的?就我年少时不懂事,首先改了个 Mozilla 字样,后面追究这历史我岂不是成了罪魁祸首?我改还不行吗?在 IE6 ,它明确自己 UserAgent 为 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) 。除去已经注定不可抹去的“Mozilla”字样,其余信息简洁,准确,清晰。但事态已经不可收拾。Opera 给这狂躁的世界添了一把火。它觉得,易容术非常炫酷呀。Opera 直接在菜单提供了 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.51 , Mozilla/5.0 (Windows NT 6.0; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.51 , Opera/9.51 (Windows NT 5.1; U; en) 三个选择项。第一个是易容成 IE ,第二个是易容成火狐,第三个才是自己,选谁就是谁!其实这并不是一件坏事。因为 Opera 是站在能够让用户通过选择,去获得更好的浏览体验的基础上的。你提供选择,或是不提供,混乱的 UserAgent 还是在这,不离,不弃。再者,这对网页的开发者有极大的好处,在某些情况,你不必同时打开几个不同的浏览器去调试。到目前,最新的 Chrome 浏览器更加炫酷,能够支持近 40 种不同的 UserAgent ,甚至你还可以自定义。当然这是后话。与此同时,苹果公司依靠内核 WebKit ,开发出 Safari ,命名 UserAgent 为 Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5 。有人就会问了,不是 Webkit 内核吗,怎么还有 KHTML, like Gecko ?注意,内核 Webkit 包含了一个排版引擎叫 WebCore ,而 WebCore 是 KHTML 衍生而来的。也就是说, WebCore 是 KHTML 的儿子,子承父业,基因差不多。为了能够正常排版, safari 只能这么写。后来, google 也开发了自己的浏览器 Chrome ,其内核也是 Webkit ,但它设定 UserAgent 为 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13 。Safari一看,不对劲啊!你怎么也在后面写有 Safari ? Chrome 呵呵一笑,你懂的。因此,请让我一口气说完下面这一段:Chrome 希望能得到为 Safari 编写的网页,于是决定装成 Safari , Safari 使用了 WebKit 渲染引擎,而 WebKit 呢又伪装自己是 KHTML , KHTML 呢又是伪装成 Gecko 的。同时所有的浏览器又都宣称自己是 Mozilla 。这就是整个 UserAgent 世界大战的格局…八、军阀混战将目光聚焦到国内,更是狼烟四起,混乱不堪。大家都知道,浏览器是互联网的入口,这块肥肉谁也不想丢。因而一个接一个的“国产”浏览器进入斗兽场。360 ,百度, QQ , UC ,搜狗,猎豹,遨游,世界之窗…你能说出一大堆。连淘宝,酷狗, hao123 都有浏览器,不信你搜。注意我前面“国产”两个字必须加上双引号,因为这个 made in china 并不纯。国人并没能像远古大神一样,硬生生发明一个内核出来,我们更擅长“微创新”。利用 Trident ( IE 的内核),包装一下皮肤,美化一下,就可以说:完美兼容利用 Webkit ,包装一下皮肤,美化一下,就可以说:极速浏览把两个内核都包起来,就可以说:智能双核是微创新!读书人的事,能叫偷吗?在这插播一下,浏览器的“双核”,并不是你听说手机双核电脑双核那回事。再多个核,速度也不会更快,当然这么说,会显得很厉害的样子。德艺双馨,智勇双全,名利双收,才貌双绝,夫妻双双把家还,你看带“双”字的词都很牛的。但我上面的叙述,的确有夸张的成分。浏览器的诞生,肯定不仅仅是包一下皮肤那么简单,国内的工程师们,也苦心研究做了许多工作。如果要说优化策略,我可以再写一篇超级长的文章。优化无止境,路漫漫其修远,向同行们致敬。只是我非常讨厌那些不把事实说清楚,纯粹靠文案去忽悠人的产品…话说回来,这么多国产浏览器,总得靠不同 UserAgent 标志自己呀。大家自动分为两个阵营:使用 Trident 内核的,在 IE 已有 UserAgent 后添加自己的名称;使用 Webkit 内核的,就在 Chrome 的 UserAgent 后面添加。前者像 QQ 浏览器: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.7.26717.400) 。后者像猎豹: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36 LBBROWSER 。当然双核浏览器诚然就是墙头草,切换内核时 UserAgent 也需要跟着变化。如此的混战格局,这厢的 IE 和 Chome 想必也是醉了。九、国共内战适者生存是不变的生存法则,国产浏览器们经过一段时间的用户筛选,自然优胜劣汰。时值 2010 年,真正还在运营和更新的浏览器数量慢慢下降,用户集中在几家表现更优异的厂商手中。就在这时,好看的故事来了—— 3Q 大战爆发。有人说,腾讯电脑管家的推出是导火索。其实这场仗,大家都忍了好久,推不推出,都一定会在某个事件后爆发。 360 浏览器是奇虎的重量级产品,用户量众多, 2009 年它推出一个功能:过滤其它网站的广告。诚然民众们都很喜欢。可是其他互联网公司肯定就不乐意了,用户看不到更点击不到广告,这钱还怎么赚?因而在 3Q 大战爆发后,腾讯的一个手段就是:如果你使用 360 浏览器,就不能访问 QQ 的网站(单单 QQ 空间就有巨大的用户量),也直接反攻 360 的最大收入来源。一个艰难的决定背后,往往是需要无数种的技术战略支撑的。企鹅判断用户是否使用 360 浏览器,依靠的就是 UserAgent 里是否有“360SE”的字样。战报传来:号外, 360 浏览器上不了 QQ 空间!已经买了黄钻的杀马特贵族急了呀!只能换浏览器了呀!感覺侢乜卟哙噯嘞呀!2011年11月3日,腾讯网站封杀 360 浏览器2011年11月4日,360 浏览器访问量仅为昨日一半2011年11月5日,360 浏览器访问量几乎为 0有人说,腾讯就这么快赢了?恰恰相反,360 浏览器通过一次强制的自动升级,又可以访问 QQ 的网站了。 360 的工程师们在 5 日使用了伪装术——把“360SE”字样从 UserAgent 中去掉!意思就是, 360 浏览器的 UserAgent 跟 IE 完全一样,你根本判断不出来(因而访问量为 0 )。就怕流氓有文化!企鹅傻眼了,总不能把大微软的 IE 也一并给禁了吧…这场土匪遇恶霸的耍流氓大战,最终通过法律而化解。企鹅在技术侧拿 360 没办法,而 360 则得到了一个跟 IE 一样的身份证。在这场内战中,受伤的除了广大网民们,其实还有令人心疼 UserAgent 君,以往让它越长越长就算了,这次长了还得阉割掉,真心 dan 疼呀。十、明日边缘看到这里,大家会明白一个道理:如果未来不出现一款霸主级别的浏览器(或内核), UserAgent 应该不会有大变化了。不过,这道理并不全对。别忘了,移动侧也是有浏览器的。在早期能上网的手机里,内置了各手机厂商自研的浏览器。这些浏览器并不需要像 PC一样的复杂设计,可以访问 wap 网页就足够了。因而它们的 UserAgent 命名,怎么简单怎么来,就直接叫 诺基亚 3100 Nokia3100/06.01 (UCWEB 3.3B) , PHILIPS755 ObigoInternetBrowser/2.0 这样,有甚者连浏览器叫什么都不带 TCL-3199 , 三星 E618 SEC-SGHE618 。这样任由发展下去,一种要历史重演,往日重现的即视感压迫而来。web 世界的联合国 —— W3C 组织,站在明日边缘,面对着历史和未来,终于发话,它制定 UserAgent 标准,以后都得按这规范去起名字。详细请阅 User Agent Accessibility Guidelines 。至此,命运坎坷的 UserAgent 终于逐步走向规范。 W3C 大法好,有人说你怎么不早点来拯救世界呀!其实 W3C 一直在努力,但规范的制定,到推广至大家认可并执行,是一条漫长的道路,需要时间,也需要实践。W3C 组织,在制定 web 标准这件工作之外,再我看来,还有两个身份:1、和事佬;2、背黑锅。和事不成,就得背黑锅。是的就是这样。彩蛋那么,我们的故事接近尾声。还有一些有趣的小彩蛋。Chome 28 开始,与苹果正式分道扬镳,采用 Blink 内核,但它的 UserAgent 并不改变。淘宝封杀微信打开淘宝页面,靠的就是微信内置浏览器 UserAgent 里的 MicroMessenger 字样。其实微信也可以像当初 360 一样把 UserAgent 去掉,但微信并不这样做。360 出招之时留有后招。也许,它一开始就想到了腾讯会告他们对于 UserAgent 的欺瞒,因而它其实提供了设置项。默认设置是“保持跟 IE 一样的 UserAgent ”,但用户也可以不勾选。只是这选项比较隐蔽,而且你重启浏览器后…又会变回默认设置。如果没有这个小小的设置,结果大家可以自行想象。微软又玩新花样了,在泄露版 IE11 中,去掉了以往的 MSIE 字样。初步猜测此举是为了使现有的 CSS hack 失效,避免过去网页设计师对 IE 差别对待的情况再度发生。但又会引发其他问题啊亲。注:本文转载自 Litten 的文章“浏览器野史 UserAgent 列传 (上) (下)” ,内容二合一,特此注明!
2020年05月24日
4,062 阅读
0 评论
0 点赞
1
2
3
4
...
18