前言

懒得看的直接跳转脚本源码

AI开课还要布置作业,你无敌了。我寻思这课不是考察吗?

学银在线提交作业界面甚至无法粘贴,会提示“只能录入不能粘贴!”

什么垃圾玩意?看我干不干你就完事了。

破解

定位代码&修改

这种禁止粘贴100%是JS+前端拦截。直接进控制台搜源代码,定位到:

监听函数

然后直接写脚本替换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// ==UserScript==
// @name 学银在线允许粘贴
// @namespace https://blog.esing.dev/
// @version 0.7.2.1
// @description 移除学银在线的编辑器限制,允许粘贴
// @match https://mooc1.xueyinonline.com/mooc-ans/*
// @run-at document-end
// @grant unsafeWindow
// ==/UserScript==

(function() {
'use strict';

function overrideEditorPaste() {
try {
if (typeof unsafeWindow.editorPaste === 'function') {
unsafeWindow.editorPaste = function(o, html) {
// 不清空 html.html,让编辑器正常插入粘贴内容
// 也不再弹“只能录入不能粘贴!”
// 一般返回 true/不返回都可以,看编辑器实现习惯
// 这里返回 true,表示允许粘贴
return true;
};
console.log('[Tampermonkey] editorPaste overridden, paste is now allowed.');
return true;
}
} catch (e) {
console.error('[Tampermonkey] Failed to override editorPaste:', e);
}
return false;
}

// 尝试覆盖一次
overrideEditorPaste();

// 有些站点会晚一点才定义 editorPaste,这里每隔 1 秒再尝试一下
const timer = setInterval(function() {
if (overrideEditorPaste()) {
clearInterval(timer); // 覆盖成功后就不用再重复尝试了
}
}, 1000);
})();

塞进油猴测试。

没有效果?那继续。

分析输入框代码

继续检查元素,定位到输入框代码。检查一下可以发现,这里有个奇怪的script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<div class="stem_answer" style="">
<div class="eidtDiv" style="">
<div class="edui-default" style="">
<!-- ... -->
</div>
<textarea id="answer1919810" name="answer1919810" _initadjustheight="36" style="height: 72px; display: none">FUCKOFF</textarea>
<script>
var wordNum = "";
if (wordNum == "") {
wordNum = 0;
}
var wordMinNum = "";
if (wordMinNum == "") {
wordMinNum = 0;
}
var qtype = "4";
// var wordCount = false;
// if (qtype == 4) {
// wordCount = true;
// }
window.UEDITOR_CONFIG.initialFrameHeight = 150;
var wordCount = true;
if (parseInt(wordNum) == 0 && parseInt(wordMinNum) == 0) {
wordCount = false;
}
window.UEDITOR_CONFIG.wordCount = wordCount;
window.UEDITOR_CONFIG.wordCountTimer = false;
// window.UEDITOR_CONFIG.maximumWords = wordNum;
// window.UEDITOR_CONFIG.minimumWords = wordMinNum;

<!-- 编辑器定义代码 -->
var editor1 = UE.getEditor("answer1919810", { pasteplain: true });

editor1.options.maximumWords = wordNum;
editor1.options.minimumWords = wordMinNum;
editor1.addListener("blur", function () {
var count = UE.getEditor("answer1919810").pureWordCount();
var max = parseInt(UE.getEditor("answer1919810").options.maximumWords);
var min = parseInt(UE.getEditor("answer1919810").options.minimumWords);
if (count == 0) {
$("#answer1919810").parent().find(".edui-editor.edui-default").removeClass("borblue");
$("#answer1919810").parent().find(".edui-editor.edui-default").removeClass("borred");
} else if ((max > 0 && count > max) || (min > 0 && min > count)) {
$("#answer1919810").parent().find(".edui-editor.edui-default").removeClass("borblue");
$("#answer1919810").parent().find(".edui-editor.edui-default").addClass("borred");
return;
} else {
$("#answer1919810").parent().find(".edui-editor.edui-default").removeClass("borblue");
$("#answer1919810").parent().find(".edui-editor.edui-default").removeClass("borred");
}
});
editor1.addListener("focus", function () {
$("#answer1919810").parent().find(".edui-editor.edui-default").addClass("borblue");
$("#answer1919810").parent().find(".edui-editor.edui-default").removeClass("borred");
});

<!-- 粘贴许可相关 -->
var allowPaste = "1";
if (parseInt(allowPaste) == 1) {
editor1.addListener("beforepaste", editorPaste);
}
<!-- 一个奇怪的监听器 -->
editor1.addListener("contentChange", function () {
loadEditorAnswerd(1919810, 4);
answerContentChange();
});
<!-- 应该就是你了 -->

window.UEDITOR_CONFIG.wordCount = false;
</script>
</div>
</div>

可知:这个编辑器是百度的UEditor,且在beforepaste事件上面挂了editorPaste这个回调函数。因此,真正要干掉的是所有的UEditor上面挂的beforepaste监视器。

修改脚本

把UEditor上面挂的beforepaste监视器拿掉即可。注意看函数上面有个addListener("beforepaste", editorPaste),这是挂上去的代码。那我removeListener你不炸了吗?

直接把需求告诉AI让它修改就行了。AI太好用了你们知道吗

脚本源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// ==UserScript==
// @name 学银在线允许粘贴
// @namespace https://blog.esing.dev/
// @version 0.7.2.1
// @description 移除学银在线的编辑器限制,允许粘贴
// @match https://mooc1.xueyinonline.com/mooc-ans/*
// @run-at document-end
// @grant none
// ==/UserScript==

(function () {
"use strict";

// 尝试对所有 UEditor 实例移除 beforepaste 的 editorPaste 监听
function unlockPaste() {
// UEditor 全局对象一般叫 UE
if (!window.UE || !UE.instants) return false;

let done = false;
for (const key in UE.instants) {
if (!Object.prototype.hasOwnProperty.call(UE.instants, key)) continue;
const ed = UE.instants[key];
try {
// 如果全局有 editorPaste 函数,并且这个编辑器有 removeListener 方法
if (typeof window.editorPaste === "function" && ed.removeListener) {
ed.removeListener("beforepaste", window.editorPaste);
console.log("[Userscript] removed beforepaste listener from editor:", key);
done = true;
}
} catch (e) {
console.error("[Userscript] removeListener error:", e);
}
}
return done;
}

// 初次尝试
unlockPaste();

// 有时候编辑器是异步初始化的,这里轮询几次,确保挂到实例上之后再移除
const timer = setInterval(() => {
if (unlockPaste()) {
clearInterval(timer);
}
}, 1000);

if (!document.getElementById("paste-unlock-indicator")) {
const div = document.createElement("div");
div.id = "paste-unlock-indicator";
div.textContent = "粘贴已解锁😋";
div.style.cssText =
"position:fixed;bottom:10px;right:10px;padding:4px 8px;font-size:12px;background:#4caf50;color:#fff;z-index:99999;border-radius:4px;opacity:0.7;";
document.body.appendChild(div);
}
})();

收工。