东南大学硕博人文讲座预约Web页面注入策略

预约页面:http://ehall.seu.edu.cn/gsapp/sys/jzxxtjapp/*default/index.do?t_s=1635836530422#/hdyy

纯Web策略

在预约开启前,使用浏览器的“开发者工具”,将被禁用的、显示为“未开放”的讲座预约按钮的HTML代码使用下面的代码替换:

<button type="button" class="bh-btn bh-btn-primary bh-col-md-1" data-action="appointment" data-wid="XXXXX">预约</button>

随后,将data-wid属性中的值使用对应讲座的“查看活动详情”按钮的HTML属性data-x-wid中的值替换。

此时按钮的注入完成,待预约开放后直接点击按钮即可。注意:预约开放前勿点击被注入按钮,否则将导致页面被刷新。

TamperMonkey脚本范例:

// ==UserScript==
// @name         东南大学硕博人文讲座预约系统按钮注入工具
// @namespace    http://pc-dos.scp-eq.org/
// @version      0.1
// @description  草泥马的东大硕博人文讲座预约系统
// @author       PC-DOS
// @include      *://ehall.seu.edu.cn/gsapp/sys/jzxxtjapp/*
// @icon         https://www.seu.edu.cn/_upload/tpl/09/bc/2492/template2492/favicon.ico
// ==/UserScript==
 
(function() {
    'use strict';
 
    //由于页面动态加载内容,故使用一个2000毫秒的延时执行
    //若网络延迟较大可修改此数值
    setTimeout(()=>{
        MainFunction()
    }, 2000)
 
})();
 
function MainFunction(){
    console.log("FuckSeuLectureAppointmentSystem: Started");
 
    //枚举每一个讲座块
    var arrLecturePosters = document.getElementsByClassName("bh-border bh-bColor-grey-3 bh-mv-16 hdhb"); //获取每一个活动海报
    console.log("FuckSeuLectureAppointmentSystem: %d lecture posters found.", arrLecturePosters.length);
    for (var i = 0; i < arrLecturePosters.length; i++){
        //获取讲座名字
        var sLectureName = arrLecturePosters[i].getElementsByClassName("sc-panel-thing-1-subject")[0].getElementsByClassName("sc-panel-thing-1-subjectValue")[0].innerHTML;
        //审查元素,查找子元素中的所有botton
        var arrButtons = arrLecturePosters[i].getElementsByTagName("button");
        //预设每个讲座poster存在两个button
        if (arrButtons.length >= 2){
            var btnAppoint = arrButtons[0];
            var btnLectureInfo = arrButtons[1];
            if (btnAppoint.getAttribute("disabled") == null){
                //如果讲座已经开放预约,跳过
                console.log("FuckSeuLectureAppointmentSystem: Lecture \"%s\" has been opened for applications, ignoring...", sLectureName);
            }
            else{
                //如果讲座没有开放预约,进行按钮注入
                console.log("FuckSeuLectureAppointmentSystem: Injecting the Appointment button of lecture \"%s\" ...", sLectureName);
                var sLectureId = btnLectureInfo.getAttribute("data-x-wid");
                //判断是否获取成功
                if (sLectureId != null){
                    //获取成功,继续注入
                    console.log("FuckSeuLectureAppointmentSystem: ID of lecture \"%s\" is %s.", sLectureName, sLectureId);
                    //替换预约按钮的外部HTML(outerHTML)
                    var htmlInjectedButton = "<button type=\"button\" class=\"bh-btn bh-btn-primary bh-col-md-1\" data-action=\"appointment\" data-wid=\"LECTURE_ID_HERE\">到点就点我</button>"; //待注入的HTML代码
                    btnAppoint.outerHTML = htmlInjectedButton.replace("LECTURE_ID_HERE", sLectureId);
                }
                else{
                    //获取失败,报错
                    console.log("FuckSeuLectureAppointmentSystem: Failed to get ID of lecture \"%s\".", sLectureName);
                }
            }
        }
    }
 
    console.log("FuckSeuLectureAppointmentSystem: Operation Finished.");
 
    //注册10秒定时执行,避免误操作后需要刷新页面
    setTimeout(()=>{
        MainFunction()
    }, 10000)
}

JavaScript + AJAX策略

已过时

讲座预约是通过向后端发送AJAX请求实现的。该请求调用了/gsapp/sys/jzxxtjapp/hdyy/yySave.do业务并传送讲座ID(即前述data-x-wid),通过BH_UTILS工具类向后端传送AJAX请求。可以通过直接向该接口发送AJAX请求实现注入。

TamperMonkey脚本范例:

// ==UserScript==
// @name         东南大学硕博人文讲座预约系统AJAX注入工具
// @namespace    http://pc-dos.scp-eq.org/
// @version      0.1
// @description  草泥马的东大硕博人文讲座预约系统(暴力版)
// @author       PC-DOS
// @include      *://ehall.seu.edu.cn/gsapp/sys/jzxxtjapp/*
// @icon         https://www.seu.edu.cn/_upload/tpl/09/bc/2492/template2492/favicon.ico
// ==/UserScript==
 
(function() {
    'use strict';
 
    //由于页面动态加载内容,故使用一个2000毫秒的延时执行
    //若网络延迟较大可修改此数值
    setTimeout(()=>{
        MainFunction()
    }, 2000)
 
})();
 
function MainFunction(){
    //等待依赖项BH_UTILS类库可用
    if (typeof BH_UTILS == "undefined"){
        console.log("BH_UTILS is currently undefined, pending it...");
        setTimeout(()=>{
            MainFunction()
        }, 2000)
        return;
    }
 
    console.log("FuckSeuLectureAppointmentSystemAjax: Start to send appointment requests");
 
    //讲座WID,可以从“查看活动详情”按钮的data-x-wid属性获取
    //这个地方要自己修改
    var sLectureID="0e9e5ea0162140e2b02828523164e8cb";
 
    //构造参数
    var arrParams = {
        HD_WID : sLectureID
    };
 
    //调用页面加载的BH_UTILS库,发送讲座预约AJAX请求
    console.log("FuckSeuLectureAppointmentSystemAjax: Sending appointment request of lecture ID %s", sLectureID);
    BH_UTILS.doAjax('/gsapp/sys/jzxxtjapp/hdyy/yySave.do', {paramJson : JSON.stringify(arrParams)}).done(function (sJsonData){
        console.log(sJsonData); //显示回报数据
        if (sJsonData.success){ //判断是否预约成功
            console.log("FuckSeuLectureAppointmentSystemAjax: Appointment has been made successfully, congratulations!");
            return;
        }
        else{
            //console.log("东大网信亲妈飞天");
            console.log("FuckSeuLectureAppointmentSystemAjax: AJAX request failed, retrying...");
        }
    })
 
    //注册定时执行
    setTimeout(()=>{
        MainFunction()
    }, 500)
}
it
除非特别注明,本页内容采用以下授权方式: Creative Commons Attribution-ShareAlike 3.0 License