相信对于使用 GitHub 的小伙伴来说,以上 GitHub 徽章(badge)应该都不怎么陌生吧。如果你想快速用起来,找到你想要的徽章代码 ctrl+c & ctrl+v ,再修改对应的 GitHub username/repo_name 即可。

今天我要跟你分享的是这其中的一个小徽章 - GitHub 访问徽章。

![](https://changkun.de/urlstat?mode=github&repo=talkgo/night)

一行代码搞定![1]

这么简单就接入了,那它是怎么实现?它还有其他什么特性呢?

urlstat 简介

urlstat 提供了跨网站的 pv/uv 统计。适用于 blog.changkun.de[2], golang.design/research[3] 等网站的统计。

用法一:普通模式

在页面上添加以下代码:

<script async src="//changkun.de/urlstat/client.js"></script>

该脚本将查找 ID 为 urlstat-page-pv 和 urlstat-page-uv 的元素,并在找到后更新信息。

<span id="urlstat-page-pv"><!-- info will be inserted --></span>
<span id="urlstat-page-uv"><!-- info will be inserted --></span>

以下是一个 golang.design/research 例子[4]

用法二:GitHub 模式

用户 query 参数: mode=github&repo=talkgo/night,例如:

![](https://changkun.de/urlstat?mode=github&repo=talkgo/night)

源码分析

  1. 入口函数 urlstat.go

我们可以看到该项目所用到的技术: net/httpembed.FS , MongoDB 构建了一个使用 MongoDB 存储数据的 HTTP Server。

  1. 核心的 API: handler.go

  • /urlstat: 记录访问数据

  • /urlstat/dashboard: urlstat 的后台管理系统

  • /urlstat/client.js: 提供给 html 页面使用的 client.js 代码

    • 代码的主要逻辑就是去请求数据,然后将其填充到页面的两个 span 中。

2 个结构体:statvisit 就囊括了 urlstat 的基本数据结构。

type stat struct {PagePV int64 `json:"page_pv"`PageUV int64 `json:"page_uv"`
}type visit struct {Path    string    `json:"path"    bson:"path"`IP      string    `json:"ip"      bson:"ip"`UA      string    `json:"ua"      bson:"ua"`Referer string    `json:"referer" bson:"referer"`Time    time.Time `json:"time"    bson:"time"`
}

API 还加了 allowOrigin, allowGitHubUser,用于避免不受信的来源创建统计记录。

/urlstat 对应的 handler 是 recording。

在这个函数里面通过 mode 来判断其使用的是网页版还是 GitHub 徽章版。

函数逻辑也很简单,首先解析数据,然后 saveVisit,然后再 countVisit,并将其结果返回。

徽章渲染 drawer

对于我们使用的徽章模式,项目通过 drawer 来渲染出一个 image/svg+xml badge,想要了解详细代码实现,可以参考这段代码: https://github.com/changkun/urlstat/blob/main/renderer.go[5]

渲染出来的这个是怎么在 GitHub 上显示的呢?那我们就必须得了解一下 GitHub 匿名 URL:https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-anonymized-urls[6]

文中提到 GitHub 使用 Camo,那 Camo 又是什么呢?Camo 为每个文件生成一个匿名 URL 代理,它对其他用户隐藏您的浏览器详细信息和相关信息。URL 以 https://<subdomain>.githubusercontent.com/ 开头,根据你上传图像的方式具有不同的子域。

以 GitHub talkgo/night README 为例,我们访问 GitHub 主页,就可以得到 camo 渲染代码:

<a target="_blank" rel="noopener noreferrer" href="https://camo.githubusercontent.com/142682259b230dd9ed8d7382509ecf5eab5cc54aea56d1ea7c4871292adfff8a/68747470733a2f2f6368616e676b756e2e64652f75726c737461743f6d6f64653d676974687562267265706f3d74616c6b676f2f6e69676874"><img src="https://camo.githubusercontent.com/142682259b230dd9ed8d7382509ecf5eab5cc54aea56d1ea7c4871292adfff8a/68747470733a2f2f6368616e676b756e2e64652f75726c737461743f6d6f64653d676974687562267265706f3d74616c6b676f2f6e69676874" alt="" data-canonical-src="https://changkun.de/urlstat?mode=github&amp;repo=talkgo/night" style="max-width: 100%;"></a>

为什么要使用 camo

任何在 GitHub README.md 文件(或其他呈现的 HTML 格式)中呈现的图像都将使用 camo 呈现。

有几个原因:

  1. 性能:GitHub 为大量用户提供服务,如果不这样做,页面加载时间会很糟糕。

  2. 隐私:让回购所有者嵌入跟踪图像是不可接受的。

  3. DDoS 角度:在外部托管图像允许恶意存储库所有者拥有相当流行的存储库,只需加载其中一个图像即可对他们选择的任何站点进行 DDoS 攻击。

更多详细解释,参见 Github image without camo with Stack Overflow[7]

至此一个简单的 urlstat 就算是完成了。

参考链接

[1]

一行代码搞定!: https://github.com/talkgo/night/commit/3542964480fc3e45600cff40a53abff31249609f

[2]

blog.changkun.de: https://blog.changkun.de

[3]

golang.design/research: https://golang.design/research

[4]

golang.design/research 例子: https://golang.design/research/zero-alloc-call-sched/

[5]

https://github.com/changkun/urlstat/blob/main/renderer.go: https://github.com/changkun/urlstat/blob/main/renderer.go

[6]

https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-anonymized-urls: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-anonymized-urls

[7]

参见 Github image without camo with Stack Overflow: https://stackoverflow.com/questions/57857193/github-image-without-camo

点击阅读原文,前往项目

一行代码搞定 GitHub 访问徽章相关推荐

  1. 开源作品ThinkJDBC—一行代码搞定数据库操作

    1 简介 ThinkJD,又名ThinkJDBC,一个简洁而强大的开源JDBC操作库.你可以使用Java像ThinkPHP框架的M方法一样,一行代码搞定数据库操作.ThinkJD会自动管理数据库连接, ...

  2. 一行代码搞定 FTP 服务

    环境搭建: python windows/linux pip install pyftpdlib (安装失败请到这里下载:https://pypi.python.org/pypi/pyftpdlib/ ...

  3. thinkjdbc 关闭_ThinkJD: ThinkJD,又名ThinkJDBC,一个强大的开源JDBC/ORM操作库,让你尽可能简洁地用一行代码搞定数据库操作。...

    1 简介 ThinkJD,又名ThinkJDBC,一个简洁而强大的开源JDBC操作库.你可以使用Java像ThinkPHP框架的M方法一样,一行代码搞定数据库操作.ThinkJD会自动管理数据库连接, ...

  4. Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0

    Android 一行代码搞定将错误日志放入到sd卡中且不需要任何权限,适配到android7.0 之前所有的项目都有一个将崩溃日志写入到sd卡的工具类,然后每次项目新建都从老项目copy过来,后来慢慢 ...

  5. 安卓视频播放器 一行代码快速实现视频播放,Android视频播放,AndroidMP3播放,安卓视频播放一行代码搞定,仿今日头条 Android视频播放器

    一行代码快速实现视频播放,Android视频播放,AndroidMP3播放,安卓视频播放一行代码搞定,真正实现Android的全屏功能 github地址:https://github.com/qius ...

  6. WPF使用Linq 一行代码搞定数据绑定

    首先设置好DataGrid控件的相关属性,注意XAML代码文件中的列绑定要和源数据的列名一致,如: Binding="{Binding No}" 详细设置如下: this.data ...

  7. 成功解决numpy.ndarray格式类型转数据为list格式数据带有中括号(一行代码搞定!)

    成功解决numpy.ndarray格式类型转数据为list格式数据带有中括号(一行代码搞定!) 目录 解决问题 解决思路 解决方法 解决问题 numpy.ndarray格式类型转数据为list格式数据 ...

  8. 一行代码搞定 Scrapy 随机 User-Agent 设置

    摘要:爬虫过程中的反爬措施非常重要,其中设置随机 User-Agent 是一项重要的反爬措施,Scrapy 中设置随机 UA 的方式有很多种,有的复杂有的简单,本文就对这些方法进行汇总,提供一种只需要 ...

  9. 【Python】Autoviz: 一行代码搞定数据集探索并可视化

    数据集各个特征有什么变化趋势.各个特征之间有何关系,我们可以借助Matplotlib.Seaborn等诸多工具来可视化展示,那么有没有一种工具能一次展示所有的关系了? 本文要介绍的Python工具Au ...

最新文章

  1. 【深度学习】基于Pytorch的卷积神经网络概念解析和API妙用(二)
  2. 国王放米粒的C语言程序,云南大学软件学院C语言实验米粒问题.doc
  3. WPF:动态显示或隐藏Listview的某一列
  4. Java企业面试算法新得体会之6大数据和空间限制问题6问
  5. springboot + mybatis +easyUI整合案例
  6. java解析html_java中几种解析html的工具
  7. Mac电脑如何一键打开常用的app?
  8. 小白能读懂的 《手把手教你学DSP(TMS320X281X)》第六章 时钟和系统控制
  9. Fidder实现手机抓包(ios)
  10. caxa发生文件读写异常_常见socket读写异常及错误
  11. RedHat下载安装JDK的方法(方法二)
  12. pdfbox / XSL + FOP 转换 PDF文档
  13. 维恩图是什么?如何使用维恩图?
  14. opencascade基础
  15. Android-事件分发机制(源码层面)
  16. @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) 和 @NotAudited
  17. 实现单向选择题和多项选择题的选中状态-不使用radio和CheckBox
  18. linux中top显示的信息详解,Linux中top显示信息详解
  19. 在银行存一年钱最多可以得到多少利息?
  20. 如何使用栈非递归地求解Ackerman函数

热门文章

  1. javascript php xmlhttp file,xmlHTTP实例_javascript技巧
  2. kafka是什么_终于知道Kafka为什么这么快了!
  3. 记不住ASP.NET页面生命周期的苦恼
  4. 腾讯云Service Mesh生产实践及架构演进
  5. mysql查询今天,昨天,近7天,近30天,本月,上一月数据
  6. [转]HTTP协议及其请求头分析
  7. 从原理到实践手动拼凑一个Linux系统
  8. Silverlight开发历程—(输入事件和非输入事件)
  9. CodeForces - 1567C Carrying Conundrum(思维/状压)
  10. 有向图缩点:tarjan强连通缩点(模板)