利用油猴脚本显示扇贝网真实打卡日记

前一段时间发现扇贝网页版显示的打卡日记和手机上看到的不一致,感觉应该是网页版开发滞后的原因。这种不一致给查卡带来了诸多不便,于是就设法解决该问题。

起初我想到的方案是做一个静态页面放到对象存储上,然后对象存储开启静态服务,静态页面通过Ajax请求手机版的RESTful接口获取数据,然后生成打卡日记。不过,通过反复试验发现这种方法行不通。

$.get(url, function(data){
    // do something
});

直接使用Ajax请求会报错:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是因为服务器不允许跨站。

然后接触到了用JSONP来进行跨站请求。因为js脚本可以跨站,像静态博客的评论功能就是用的跨站js脚本,JSONP的思路是在请求的地址上携带一个callback参数,服务端以这个callback参数作为函数名包裹JSON数据,然后在返回数据时调用这个函数,就把JSON数据传过来了。

$.ajax({
    url: url,
    dataType: 'jsonp',
    success: function(json){
        // do something
    }
});

但是,使用JSONP的前提同样是需要服务器端的配合。假如服务器端不适配JSONP,也就是不返回包裹JSON数据的函数,而是依旧返回JSON,那么JSON数据就会被视为javascript脚本运行,会报错:

Uncaught SyntaxError: Unexpected token :

然后想到iframe也可以跨站,于是试试iframe,结果发现依然是想多了:

Refused to display '*' in a frame because it set 'X-Frame-Options' to 'deny'.

也就是iframe也是需要服务器端配合。假如服务器端不允许iframe,那么iframe便不能跨站。

跨站请求其实也比较危险,例如XSS、CSRF。于是,我决定不通过跨站请求,而是利用油猴脚本来实现我的需求,顺便补充了点jQuery。

// ==UserScript==
// @name         显示真实打卡日记
// @namespace    https://www.shanbay.com/
// @version      0.1
// @description  显示时区、真实打卡日记、打卡时间
// @author       文剑木然
// @match        https://www.shanbay.com/checkin/user/*
// @grant        MIT
// @require      https://static.baydn.com/static/scripts/jquery-1.7.2.min.js
// ==/UserScript==

$(function(){
    var url = window.location.href
                    .replace('www.shanbay.com', 'www.shanbay.com/api/v1')
                    .replace('?page', '?ipp=10&page');
    $.get(url, function(json){
        // 显示时区
        var timezone = json.data[0].user.timezone;
        if(json.data.length > 0 && timezone !== 'Asia/Shanghai'){
            $('h2').html($('h2').html() + '(' + timezone +')');
        }
        // 修改打卡日记
        for(var i=0; i<10; i++){
            var idata = json.data[i];
            var icheckin = $('#checkin').children().eq(i);
            var number = icheckin.find('span.number');
            number.html(' ' + idata.num_checkin_days);
            var note = icheckin.find('div.note');
            if(json.data[i].note_length === 0){
                note.html(idata.info);
            }else{
                note.html(idata.info + ' , ' + idata.note);
            }
            var date = icheckin.find('div.span4');
            date.html('<strong>' + idata.checkin_date +
                      '</strong>&nbsp;&nbsp;&nbsp;&nbsp;(' +
                      idata.checkin_time.replace('T', '&nbsp;&nbsp;') + ')');
        }
    });
});

jQuery中,children()指直接子元素,.find()能递归查找子元素,.eq(i)为第i个元素。用jQuery来修改DOM还是十分简便的。

JavaScript

上一篇 向量微积分基础
下一篇 PPM、PGM、PBM图像格式剖析

添加新评论

*
*