Greasy Fork is available in English.
用于使前端按扭可点击,能少几次请求,不用刷新页面。实测是可以抢到的。
// ==UserScript==
// @name 智谱 GLM Coding Plan 订阅 抢购助手 - 2026-04-20有效
// @name:en Zhipu GLM Coding Purchase Assistant
// @namespace http://tampermonkey.net/
// @version 3.2
// @description 用于使前端按扭可点击,能少几次请求,不用刷新页面。实测是可以抢到的。
// @description:en make the button click-able so you don't need to refresh page
// @author YourName
// @match *://www.bigmodel.cn/*
// @match https://www.bigmodel.cn/glm-coding
// @match https://bigmodel.cn/glm-coding*
// @run-at document-start
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const SCRIPT_NAME = '[抢购助手1.0]';
const STOCK_VALUE = 999;
console.log(`${SCRIPT_NAME} 拦截器已启动...`);
// ==========================================
// 工具函数
// ==========================================
/**
* 判断对象是否为商品对象
* @param {Object} obj - 待检查的对象
* @returns {boolean} - 是否为商品对象
*/
function isProductObject(obj) {
return obj.price !== undefined ||
obj.productId !== undefined ||
obj.title !== undefined;
}
/**
* 递归修改对象中的售罄相关属性
* @param {Object} obj - 待修改的对象
*/
function deepModify(obj) {
if (!obj || typeof obj !== 'object') return;
// 篡改核心售罄标识
if (obj.isSoldOut === true) {
obj.isSoldOut = false;
}
if (obj.soldOut === true) {
obj.soldOut = false;
}
// 如果遇到 disabled,且该对象看起来是个商品,则强制启用
if (obj.disabled === true && isProductObject(obj)) {
obj.disabled = false;
}
// 修改库存数量
if (obj.stock === 0) {
obj.stock = STOCK_VALUE;
}
// 递归处理子属性
for (const key in obj) {
if (obj[key] && typeof obj[key] === 'object') {
deepModify(obj[key]);
}
}
}
/**
* 修改响应文本中的售罄状态
* @param {string} text - 原始响应文本
* @returns {string} - 修改后的响应文本
*/
function modifyResponseText(text) {
return text
.replace(/"isSoldOut":true/g, '"isSoldOut":false')
.replace(/"disabled":true/g, '"disabled":false')
.replace(/"soldOut":true/g, '"soldOut":false')
.replace(/"stock":0/g, `"stock":${STOCK_VALUE}`);
}
/**
* 检查响应文本是否包含售罄状态
* @param {string} text - 响应文本
* @returns {boolean} - 是否包含售罄状态
*/
function hasSoldOutStatus(text) {
return text.includes('"isSoldOut":true') ||
text.includes('"disabled":true') ||
text.includes('"soldOut":true');
}
// ==========================================
// 战术一:拦截 SSR 页面初始注入数据
// 通过劫持浏览器的 JSON 解析器,修改带有"售罄"属性的对象
// ==========================================
const originalJSONParse = JSON.parse;
JSON.parse = function(text, reviver) {
const result = originalJSONParse(text, reviver);
try {
deepModify(result);
} catch (error) {
// 静默处理错误,避免影响页面正常功能
}
return result;
};
// ==========================================
// 战术二:拦截 Fetch 接口请求
// 针对用户在页面停留时,前端向后端发起的库存/价格检查
// ==========================================
const originalFetch = window.fetch;
window.fetch = async function(...args) {
const response = await originalFetch.apply(this, args);
const contentType = response.headers.get('content-type') || '';
// 只处理 JSON 接口
if (!contentType.includes('application/json')) {
return response;
}
const clone = response.clone();
try {
let text = await clone.text();
if (hasSoldOutStatus(text)) {
console.log(`${SCRIPT_NAME} 拦截到 Fetch 售罄数据,正在执行篡改!`, args[0]);
text = modifyResponseText(text);
// 构造并返回修改后的响应
return new Response(text, {
status: response.status,
statusText: response.statusText,
headers: response.headers
});
}
} catch (error) {
// 静默处理错误
}
return response;
};
// ==========================================
// 战术三:拦截 XMLHttpRequest (兜底方案)
// ==========================================
const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
this._requestUrl = url;
return originalXHROpen.call(this, method, url, ...rest);
};
XMLHttpRequest.prototype.send = function(...args) {
this.addEventListener('readystatechange', function() {
if (this.readyState !== 4 || this.status !== 200) {
return;
}
const contentType = this.getResponseHeader('content-type') || '';
if (!contentType.includes('application/json')) {
return;
}
try {
let text = this.responseText;
if (hasSoldOutStatus(text)) {
console.log(`${SCRIPT_NAME} 拦截到 XHR 售罄数据,正在执行篡改!`, this._requestUrl);
text = modifyResponseText(text);
// 使用劫持 getter 的方式修改响应数据
Object.defineProperty(this, 'responseText', {
get: function() { return text; }
});
Object.defineProperty(this, 'response', {
get: function() { return JSON.parse(text); }
});
}
} catch (error) {
// 静默处理错误
}
});
originalXHRSend.apply(this, args);
};
})();