之前使用Hexo搭建了自己的github.io博客https://littlefogcat.github.io/。但是没有访问统计功能,让人头大。于是决定着手整一个。
首先需要有一台自己的服务器,如果没有的话就用busuanzi.js吧。(不过我总觉得数据在自己手里比较开心)
由于我对前后端开发几乎都是一窍不通,所以耗费了很多精力,不过最后还是稍有所得,在此记录。
由于浏览器的安全策略,js只可以访问相同协议、相同域名、相同端口(同源)下的资源。这就带来一个问题,博客中的js文件无法调用服务器端的接口。
为了解决非同源跨域问题,这里采用了jsonp的解决方案。由于jsonp只支持get方式,所以参数都写在url中。
js端:
var currentPageUrl = window.location.href; // 当前页面地址
// 处理服务端返回的数据
function handleCallback(jsonData) {
// 将获取到的访问量写入html中
}
// 参数
var arrivalServer = "https://myApi?callback=handleCallback&url=" + currentPageUrl;
其中myApi
是服务端暴露的获取访问量的接口,而当前页面的url作为唯一标识符做参数传递。这里是有问题的,最好还是不要把url写在参数里,可以考虑base64编码。使用window.btoa()
即可将字符串进行base64编码,反之使用window.atob()
即可进行解码。
var serverBase64 = window.btoa(arrivalServer);
callback=handleCallback
表示当服务端返回数据时,调用js里的handleCallback函数。
服务端
仅就Java而言,使用com.fasterxml.jackson.databind.util.JSONPObject
这个类可以快速创建一个jsonp对象。
示例:
// Code in Controller
@ResponseBody
@RequestMapping("/arrival")
public Object getGithubIoArrival(@RequestParam String callback,
@RequestParam String articleUrl,
@RequestParam(required = false) String ip) {
GithubIoArrivalResult result = service.getArrival(articleUrl, ip);
return new JSONPObject(callback, result);
}
由于Github Pages强制使用https访问,所以服务端也应该支持https。这篇文章有详细的步骤:5分钟内搞定 Tomcat 的 SSL 配置
如果不想整个应用都是用https,只用将url-pattern
标签的内容改成所需要的即可。
如:
首先明确需求,很简单:
这样需要两张表,一张保存每个页面的访问量(pv),一张保存详细的访问记录(record)。
逻辑很简单。当一个Get请求到达时,首先将其保存至record表中,然后再查找当天是否已经浏览过本页面。只有当这个ip当日没有浏览过本页面时,才更新pv表,本页面的浏览量+1。最后返回页面浏览数。
找到hexo博客的根目录, 修改themes\landscape\layout\_partial\head.ejs
文件。
在其中添加一行
这个搜狐的链接,用于获取当前用户的IP地址。
然后,修改themes\landscape\layout\_partial\footer.ejs
文件。添加以下内容
在url中传递url会出现问题,这是显而易见的。所以,对于每个页面,其url需要经过编码才能传给服务端。常见的方式有base64。但是js中的base64编码只支持ascii字符,并不支持中文,所以不能使用这个方法。最后选择了encodeURIComponent
来进行编码。
js端
var href = window.location.href;
href = encodeURIComponent(href)
编码前:https://littlefogcat.top/api/test/testEncodeURIComponent?param=hello你好
编码后:https%3A%2F%2Flittlefogcat.top%2Fapi%2Ftest%2FtestEncodeURIComponent%3Fparam%3Dhello%E4%BD%A0%E5%A5%BD
服务端
java.net.URLEncoder
类和java.net.URLDecoder
类和js的encodeURIComponent
、decodeURIComponent
是同样的作用。前端传递过来经过编码的url,只需要通过一句代码就能解码:
String urlDecoded = URLDecoder.decode(urlEncoded, "utf8");
LittleFogCat’s Page - https://littlefogcat.github.io/