Skip to content

Instantly share code, notes, and snippets.

@frostime
Last active November 9, 2024 05:12
Download ChatGPT Audio File
function hijackAudio(baseUrl = null) {
// https://chatgpt.com
baseUrl = baseUrl || window.location.origin;
// 保存原始函数
const originalFetch = window.fetch;
const originalXhrOpen = XMLHttpRequest.prototype.open;
let isHijacked = false;
// Helper function: 提取 Authorization 头部信息
function extractAuthorizationHeader(headers) {
if (headers instanceof Headers) {
return headers.get("Authorization");
} else {
return headers["Authorization"];
}
}
// 主函数:劫持 fetch 和 XMLHttpRequest,自动下载音频文件
function hijack() {
if (isHijacked) {
console.log("Already hijacked.");
return;
}
// 劫持 fetch 请求
window.fetch = function (url, options) {
// 检查请求 URL 是否为目标 API
if (url.includes(`${baseUrl}/backend-api/synthesize?`)) {
console.log("Found fetch request:", url);
// 获取 Authorization 头部信息
const headers = options && options.headers ? extractAuthorizationHeader(options.headers) : null;
// 修改请求 URL,将格式从 acc 改为 mp3
const modifiedUrl = url.replace(/format:acc/, "format:mp3");
// 发起修改后的请求并处理响应
return originalFetch(modifiedUrl, options).then((response) => {
return response.blob().then((blob) => {
// 创建下载链接并触发下载
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "response.mp3";
link.click();
return response;
});
});
}
// 如果不是目标请求,继续使用原始 fetch
return originalFetch.apply(this, arguments);
};
// 劫持 XMLHttpRequest 请求
XMLHttpRequest.prototype.open = function (method, url) {
// 检查请求 URL 是否为目标 API
if (url.includes(`${baseUrl}/backend-api/synthesize?`)) {
const xhr = this;
const originalOnReadyStateChange = xhr.onreadystatechange;
// 修改 onreadystatechange 以处理响应并触发下载
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
const blob = new Blob([xhr.response], { type: "application/octet-stream" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "response.mp3";
link.click();
}
// 调用原始的 onreadystatechange(如果存在)
if (originalOnReadyStateChange) {
originalOnReadyStateChange.apply(xhr, arguments);
}
};
// 修改请求 URL,将格式从 acc 改为 mp3
const modifiedUrl = url.replace(/format:acc/, "format:mp3");
// 保持 Authorization 头部信息
const authorizationHeader = xhr.getRequestHeader("Authorization");
if (authorizationHeader) {
xhr.setRequestHeader("Authorization", authorizationHeader);
}
// 使用修改后的 URL 调用原始的 open 方法
originalXhrOpen.call(this, method, modifiedUrl);
} else {
// 如果不是目标请求,继续使用原始 open 方法
originalXhrOpen.apply(this, arguments);
}
};
isHijacked = true;
console.log("Hijack activated and listeners set.");
}
// 重置函数:恢复原始状态
function reset() {
if (!isHijacked) {
console.log("Not hijacked yet.");
return;
}
window.fetch = originalFetch;
XMLHttpRequest.prototype.open = originalXhrOpen;
isHijacked = false;
console.log("Reset completed. Original functions restored.");
}
return {
hijack,
reset
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment