Greasy Fork is available in English.

保存fetch和xhr

自动保存/备份 fetch/xhr/ajax请求响应的脚本,导出为json文件,可以用于多种用途,比如说自动保存浏览过的b站视频评论、收藏夹、知乎回答、知乎评论、知乎收藏、小红书评论、百度网盘文件列表等等。初始目的为弥补https://archive.org/无法保存动态加载的网页的问题。而且f12 network export har无法仅保存某些请求,且步骤比较繁琐,无法自动。

// ==UserScript==
// @name         保存fetch和xhr
// @namespace    http://tampermonkey.net/
// @version      2024-04-08
// @description  自动保存/备份 fetch/xhr/ajax请求响应的脚本,导出为json文件,可以用于多种用途,比如说自动保存浏览过的b站视频评论、收藏夹、知乎回答、知乎评论、知乎收藏、小红书评论、百度网盘文件列表等等。初始目的为弥补https://archive.org/无法保存动态加载的网页的问题。而且f12 network export har无法仅保存某些请求,且步骤比较繁琐,无法自动。
// @author       You
// @match        https://www.zhihu.com/collection/*
// @match        https://www.zhihu.com/people/*
// @match        https://*.bilibili.com/*
// @match        https://cloud.heytap.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=zhihu.com
// @require https://update.greasyfork.org/scripts/472943/1320613/Itsnotlupus%27%20MiddleMan.js
// @run-at document-start
// @grant    GM_setValue
// @grant    GM_listValues
// @grant    GM_getValue
// @grant    GM_deleteValue
// @grant    GM_notification
// @license      LGPLv3
// ==/UserScript==



newFunction("https://www.zhihu.com/api/v4/*");
newFunction("https://api.bilibili.com/x/v3/*");
newFunction("https://api.bilibili.com/x/space/wbi/arc/search*");
newFunction("https://ck-rest-cn.heytap.com/albumpc/v3/albumDetail");
newFunction("https://api.bilibili.com/x/v2/reply/wbi/*");



function newFunction(hookUrl) {
	middleMan.addHook(hookUrl, {
		async responseHandler(request, response, error) {
			// console.log("snooped on response:",request, response, error);
			// console.log(await response?.json())
			// let jsonString = JSON.stringify(await response?.json());
			let jsonString = await response.json(); // 可以是对象不转换为字符串


			// gpt,使用GM_setValue将response.url作为key把json存储起来
			if (jsonString && response.url) {
				GM_setValue(response.url, jsonString);
			}
		}
	});
}

// gpt,使用GM_listValues和GM_getValue函数,获取所有保存的键值对为一个对象
// 获取所有保存的键值对并组成一个对象
function savedJson() {
	let savedData = {};
	let keys = GM_listValues();
	keys.forEach(key => {
		let value = GM_getValue(key);
		savedData[key] = value;
	});
	// 将savedData对象下载为一个json文件
	downloadFunc(savedData)
}

function downloadFunc(params) {
	// 创建一个 JSON 字符串
	let jsonData = JSON.stringify(params);
	// 创建一个新的 Blob 对象
	let blob = new Blob([jsonData], {
		type: 'application/json'
	});
	// 创建一个临时 URL,用于下载 JSON 文件
	let url = URL.createObjectURL(blob);
	// 创建一个隐藏的链接
	let a = document.createElement('a');
	a.style.display = 'none';
	a.href = url;

	let currentDate = new Date(+new Date() + 8 * 3600 * 1000).toISOString().slice(0, 19).replace(/[-T:/]/g, ''); // 获取当前日期和时间
	a.download = 'savedResponse_' + currentDate + '.json'; // 文件名包含当前日期和时间 // gpt,'savedResponse这里加上当前的日期和时间.json'


	document.body.appendChild(a);

	a.onclick = (e) => {
		e.stopPropagation();
	}
	// 触发点击事件来下载文件
	a.click();
	// 释放 URL 对象
	URL.revokeObjectURL(url);
}


// clearSavedData 函数用于执行清空操作
function clearSavedData() {
	// 获取所有保存的键值对
	let keys = GM_listValues();

	// 遍历所有键并删除对应的值
	keys.forEach(key => {
		GM_deleteValue(key);
	});

	// 提示用户清空完成(可选)
	// alert('保存的响应数据已清空');
	GM_notification({
		title: '数据已清空',
		text: '保存的数据已清空',
		timeout: 3000 // 通知显示时间,单位为毫秒
	});
}

let top = 0
// gpt,在页面右上方添加一个按钮,点击这个按钮,调用savedJson函数
function addButton(textContent, listener) {
	// 创建一个按钮
	let button = document.createElement('button');

	button.textContent = textContent;
	button.style.position = 'fixed';
	button.style.top = top + 50 + 'px';
	top += 50;
	button.style.right = '10px';
	button.style.zIndex = '9999';

	// 添加点击事件
	button.addEventListener('click', listener);

	// 添加鼠标悬停和离开事件处理
	button.addEventListener('mouseenter', function () {
		button.style.backgroundColor = '#ddd'; // 鼠标悬停时的颜色
	});

	button.addEventListener('mouseleave', function () {
		button.style.backgroundColor = ''; // 鼠标离开时恢复原色
	});

	// 将按钮添加到页面
	document.body.appendChild(button);

	// gpt,给这个按钮添加鼠标悬停变色的效果
}


// setTimeout(addButton('下载保存的所有请求数据', savedJson), 3000);
setTimeout(() => addButton('下载保存的所有请求数据', savedJson), 3000);
setTimeout(() => addButton('清空', clearSavedData), 3000);

console.log(123);