diff --git a/enums/AreaNameEnum.js b/enums/AreaNameEnum.js index e9d28ec..b50daeb 100644 --- a/enums/AreaNameEnum.js +++ b/enums/AreaNameEnum.js @@ -1,15 +1,144 @@ -const path = require("node:path"); - - const AreaNameEnum = Object.freeze({ - YUN_NAN: Object.freeze({ - AREA_CODE: '5300', - AREA_NAME: 'yunnan', + BEI_JING: Object.freeze({ + AREA_CODE: '1100', + AREA_NAME: 'beijing', + }), + TIAN_JING: Object.freeze({ + AREA_CODE: '1200', + AREA_NAME: 'tianjing', + }), + HE_BEI: Object.freeze({ + AREA_CODE: '1300', + AREA_NAME: 'hebei', + }), + NEI_MENG: Object.freeze({ + AREA_CODE: '1500', + AREA_NAME: 'neimeng', + }), + LIAO_NING: Object.freeze({ + AREA_CODE: '2100', + AREA_NAME: 'liaoning', + }), + DA_LIAN: Object.freeze({ + AREA_CODE: '2102', + AREA_NAME: 'dalian', + }), + JI_LIN: Object.freeze({ + AREA_CODE: '2200', + AREA_NAME: 'jilin', + }), + HEI_LONG_JIANG: Object.freeze({ + AREA_CODE: '2300', + AREA_NAME: 'heilongjiang', + }), + SHANG_HAI: Object.freeze({ + AREA_CODE: '3100', + AREA_NAME: 'shanghai', + }), + JIANG_SU: Object.freeze({ + AREA_CODE: '3200', + AREA_NAME: 'jiangsu', + }), + ZHE_JIANG: Object.freeze({ + AREA_CODE: '3300', + AREA_NAME: 'zhejiang', + }), + NING_BO: Object.freeze({ + AREA_CODE: '3302', + AREA_NAME: 'ningbo', + }), + AN_HUI: Object.freeze({ + AREA_CODE: '3400', + AREA_NAME: 'anhui', + }), + FU_JIAN: Object.freeze({ + AREA_CODE: '3500', + AREA_NAME: 'fujian', + }), + XIA_MEN: Object.freeze({ + AREA_CODE: '3502', + AREA_NAME: 'xiamen', + }), + JIANG_XI: Object.freeze({ + AREA_CODE: '3600', + AREA_NAME: 'jiangxi', + }), + SHAN_DONG: Object.freeze({ + AREA_CODE: '3700', + AREA_NAME: 'shandong', + }), + QING_DAO: Object.freeze({ + AREA_CODE: '3702', + AREA_NAME: 'qingdao', + }), + HE_NAN: Object.freeze({ + AREA_CODE: '4100', + AREA_NAME: 'henan', }), HU_BEI: Object.freeze({ AREA_CODE: '4200', AREA_NAME: 'hubei', }), + HU_NAN: Object.freeze({ + AREA_CODE: '4300', + AREA_NAME: 'hunan', + }), + GUANG_DONG: Object.freeze({ + AREA_CODE: '4400', + AREA_NAME: 'guangdong', + }), + SHEN_ZHEN: Object.freeze({ + AREA_CODE: '4403', + AREA_NAME: 'shenzhen', + }), + GUANG_XI: Object.freeze({ + AREA_CODE: '4500', + AREA_NAME: 'guangxi', + }), + HAI_NAN: Object.freeze({ + AREA_CODE: '4600', + AREA_NAME: 'hainan', + }), + CHONG_QING: Object.freeze({ + AREA_CODE: '5000', + AREA_NAME: 'chongqing', + }), + SI_CHUAN: Object.freeze({ + AREA_CODE: '5100', + AREA_NAME: 'sichuan', + }), + GUI_ZHOU: Object.freeze({ + AREA_CODE: '5200', + AREA_NAME: 'guizhou', + }), + YUN_NAN: Object.freeze({ + AREA_CODE: '5300', + AREA_NAME: 'yunnan', + }), + XI_ZANG: Object.freeze({ + AREA_CODE: '5400', + AREA_NAME: 'xizang', + }), + SHAN_XI: Object.freeze({ + AREA_CODE: '6100', + AREA_NAME: 'shanxi', + }), + GAN_SU: Object.freeze({ + AREA_CODE: '6200', + AREA_NAME: 'gansu', + }), + QING_HAI: Object.freeze({ + AREA_CODE: '6300', + AREA_NAME: 'qinghai', + }), + NING_XIA: Object.freeze({ + AREA_CODE: '6300', + AREA_NAME: 'ningxia', + }), + XIN_JIANG: Object.freeze({ + AREA_CODE: '6500', + AREA_NAME: 'xinjiang', + }), getByAreaCode(areaCode) { if (areaCode == null) { diff --git a/routes/index.js b/routes/index.js index 926d214..03542cc 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,15 +1,12 @@ const express = require("express"); const router = express.Router(); -const {jsdomFromText, browser} = require("sdenv"); -const {Script} = require("node:vm"); const crypto = require("node:crypto") const AreaNameEnum = require('../enums/AreaNameEnum'); -const Store = require("../utils/Store"); -const JsUtil = require('../utils/JsUtil'); -let store = new Store(); -let sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); +const Rs6Service = require("./service/Rs6Service"); + +rs6Service = new Rs6Service() router.post('/rsCookie', async (req, res) => { let uuid = crypto.randomUUID().replace(/-/g, ""); @@ -17,21 +14,34 @@ router.post('/rsCookie', async (req, res) => { try { let url = req.body['url']; let areaName = req.body['areaName']; - let htmlStr = req.body['htmlBase64']; - let cookie = req.body['cookieBase64']; - let userAgent = req.body['userAgentBase64']; + let htmlBase64 = req.body['htmlBase64']; + let cookieBase64 = req.body['cookieBase64']; + let userAgentBase64 = req.body['userAgentBase64']; console.log(`${uuid};接收到 ${areaName} 请求:${url}`) + // 参数判断 + let areaCode = AreaNameEnum.getByAreaName(areaName).AREA_CODE; + if (areaCode == null) { + return res.status(500).send('error areaCode') + } if (url == null || url === '') { return res.status(500).send('error url') } - if (htmlStr == null || htmlStr === '') { + if (htmlBase64 == null || htmlBase64 === '') { return res.status(500).send('error html') } - - let cookies = await handle(url, uuid, areaName, Buffer.from(htmlStr, 'base64').toString('utf-8'), cookie != null && cookie !== "" ? Buffer.from(cookie, 'base64').toString('utf-8') : null, userAgent != null && userAgent !== "" ? Buffer.from(userAgent, 'base64').toString('utf-8') : null,) - + // 参数处理 + let htmlStr = Buffer.from(htmlBase64, 'base64').toString('utf-8'); + let cookieStr = null; + if (cookieBase64 != null && cookieBase64 !== '') { + cookieStr = Buffer.from(cookieBase64, 'base64').toString('utf-8'); + } + let userAgent = null; + if (userAgentBase64 != null && userAgentBase64 !== "") { + userAgent = Buffer.from(userAgentBase64, 'base64').toString('utf-8'); + } + // 执行 + let cookies = await rs6Service.handle(url, uuid, areaName, htmlStr, cookieStr, userAgent) console.log(`${uuid};返回cookie ---->`, cookies) - res.status(200).send(cookies); } catch (e) { console.error(e.stack) @@ -42,206 +52,6 @@ router.post('/rsCookie', async (req, res) => { }) -function CookieStr2List(cookies) { - let list = [] - for (let cookie of cookies.trim().split("; ")) { - list.push(cookie); - } - return list -} - -async function handle(url, uuid, areaName, htmlStr, cookie, userAgent) { - // 获取 origin - let baseUrl = new URL(url).origin; - // 初始化 jsDom 和 cookieJar - const [jsDom, cookieJar] = jsdomFromText({ - url: url, referrer: url, userAgent: userAgent, contentType: "text/html", runScripts: "outside-only", // runScripts: 'dangerously'/'outside-only' - }) - // 加载dom - let dom = await jsDom(htmlStr); - console.log(`${uuid};html 加载长度--->`, dom.serialize().length) - window = dom.window - // ------------------------------------------------ param ---------------------------------------------------------- - // 标志判断cookie是否生成 - window[uuid] = false - - - // ------------------------------------------------ function ------------------------------------------------------- - // js执行成功后会跳转页面 会触发onbeforeunload钩子 - window.onbeforeunload = async (url) => { - console.debug(`${url} 页面回调完成`); - window[uuid] = true - } - - // 设置 cookie - if (cookie != null) { - let cookieList = CookieStr2List(cookie); - console.log(`${uuid};cookie 加载长度--->`, cookieList.length, baseUrl) - for (let i = 0; i < cookieList.length; i++) { - cookieJar.setCookieSync(cookieList[i], baseUrl); - } - } - - // 方案1 通过监听cookie 判断cookie是否生成 - const superSetCookie = cookieJar.setCookie; - let generateCookieKey = null; - // 设置 setCookie 代理 - cookieJar.setCookie = function (cookie, currentUrl, options, callback) { - console.debug(`${uuid};正在设置 Cookie:`, cookie, currentUrl); - let call = superSetCookie.call(this, cookie, currentUrl, options, callback); - // 根据瑞树6 cookie 特性 截取 `enable_XXXXXXXXXXXX=true` XXXXXXXX 为即将生成的 cookie key - if (generateCookieKey != null && cookie.includes(generateCookieKey)) { - window[uuid] = true - console.debug('匹配---->', cookie) - } - let match = cookie.match(/enable_(.*?)=true/); - if (match) { - generateCookieKey = match[1]; - console.debug('设置 匹配---->', generateCookieKey) - } - return call; - }; - - // ------------------------------------------------ 实例化浏览器 ----------------------------------------------------- - browser(window, 'chrome'); - // 加载js - let js = await JsUtil.loadJs(window.document, areaName, cookie); - console.log(`${uuid};js 加载长度--->`, js.length) - - - // 执行 js - let script = new Script(js); - let internalVMContext = dom.getInternalVMContext(); - script.runInContext(internalVMContext, {timeout: 1000}); - - // 等待 cookie 被设置 - for (let i = 0; i < 10; i++) { - if (window[uuid]) { - break; - } - await sleep(100) - } - // 获取cookie - let resCookie = cookieJar.getCookieStringSync(baseUrl); - // 关闭 - dom.window.close() - return resCookie; -} - -/** - * 方案1 - * 利用rs特性 js加载完成后会刷新页面 - * 利用 window.onbeforeunload 判断页面是否执行完毕 - * @param window - * @param cookieJar - * @param uuid - * @returns {Promise<*|null>} - */ -function scheme1_before(window, cookieJar, uuid) { - window.onbeforeunload = async (url) => { - let baseUrl = new URL(url).origin; - const cookies = cookieJar.getCookieStringSync(baseUrl); - console.debug(`${url} 页面回调生成cookie:`, cookies); - store.set(uuid, cookies) - // window.close(); - } -} - -/** - * 方案1 - * @param window - * @param cookieJar - * @param uuid - * @returns {Promise<*|null>} - */ -async function scheme1_after(window, cookieJar, uuid) { - // 等待 onbeforeunload 钩子触发后的回掉 - let val = await store.waitGetAndDelete(uuid, 100, 10) - if (val != null) { - return val; - } - return null; -} - - -/** - * 监听cookie出现指定cookie - * @param window - * @param cookieJar - * @param uuid - * @returns {Promise} - */ -function scheme2_before(window, cookieJar, uuid) { - // window[uuid] = false; - const superSetCookie = cookieJar.setCookie; - // 设置 setCookie 代理 - cookieJar.setCookie = function (cookie, currentUrl, options, callback) { - console.log(`${uuid};正在设置 Cookie:`, cookie, currentUrl); - return superSetCookie.call(this, cookie, currentUrl, options, callback); - // let cookieStringSync = super.getCookieStringSync(); - // console.log(cookieStringSync) - // if (cookie.includes(key)) { - // // 设置标志可取标志 - // window[uuid] = true - // } - // return call; - }; -} - -/** - * 方案2 - * @param window - * @param cookieJar - * @param key - * @param uuid - * @returns {Promise} - */ -async function scheme2_after(window, cookieJar, key, uuid) { - let sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - for (let i = 0; i < 10; i++) { - let cookieStringSync = cookieJar.getCookieStringSync(); - if (cookieStringSync.includes(key)) { - return cookieStringSync; - } - await sleep(100) - } - return null; -} - -/** - * 方案3 根据cookie现有的数量判断 - * @param window - * @param cookieJar - * @param baseUrl - * @param uuid - */ -function scheme3_before(window, cookieJar, baseUrl, uuid) { - const initCookie = cookieJar.getCookieStringSync(baseUrl); - window[uuid + 'CookieSize'] = initCookie != null ? initCookie.trim().split("; ").length : 0; -} - -/** - * 方案3 - * @param window - * @param cookieJar - * @param baseUrl - * @param uuid - * @returns {Promise} - */ -async function scheme3_after(window, cookieJar, baseUrl, uuid) { - let initCookieLength = window[uuid + 'CookieSize'] - let sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - for (let i = 0; i < 10; i++) { - let cookieStringSync = cookieJar.getCookieStringSync(baseUrl); - let cookies = cookieStringSync != null ? cookieStringSync.trim().split("; ").length : 0; - if (cookies > initCookieLength) { - return cookieStringSync; - } - await sleep(100) - } - return null; -} - // 测试 handle // handle('https://app.yunnan.chinatax.gov.cn/xxmh/html/dfts/index_frame.html', diff --git a/routes/service/Rs6Service.js b/routes/service/Rs6Service.js new file mode 100644 index 0000000..926cfb6 --- /dev/null +++ b/routes/service/Rs6Service.js @@ -0,0 +1,212 @@ +const {jsdomFromText, browser} = require("sdenv"); +const JsUtil = require("../../utils/JsUtil"); +const {Script} = require("node:vm"); +const Store = require("../../utils/Store"); +let TimeUtil = require("../../utils/TimeUtil"); + +class Rs6Service { + store = new Store(); + + // service handle + async handle(url, uuid, areaName, htmlStr, cookie, userAgent) { + // 获取 origin + let baseUrl = new URL(url).origin; + // 初始化 jsDom 和 cookieJar + const [jsDom, cookieJar] = jsdomFromText({ + url: url, referrer: url, userAgent: userAgent, contentType: "text/html", runScripts: "outside-only", // runScripts: 'dangerously'/'outside-only' + }) + // 加载dom + let dom = await jsDom(htmlStr); + console.log(`${uuid};html 加载长度--->`, dom.serialize().length) + window = dom.window + // ------------------------------------------------ param ---------------------------------------------------------- + // 标志判断cookie是否生成 + window[uuid] = false + + + // ------------------------------------------------ function ------------------------------------------------------- + // js执行成功后会跳转页面 会触发onbeforeunload钩子 + window.onbeforeunload = async (url) => { + console.debug(`${url} 页面回调完成`); + window[uuid] = true + } + + // 设置 cookie + if (cookie != null) { + let cookieList = this.CookieStr2List(cookie); + console.log(`${uuid};cookie 加载长度--->`, cookieList.length, baseUrl) + for (let i = 0; i < cookieList.length; i++) { + cookieJar.setCookieSync(cookieList[i], baseUrl); + } + } + + // 方案1 通过监听cookie 判断cookie是否生成 + const superSetCookie = cookieJar.setCookie; + let generateCookieKey = null; + // 设置 setCookie 代理 + cookieJar.setCookie = function (cookie, currentUrl, options, callback) { + console.debug(`${uuid};正在设置 Cookie:`, cookie, currentUrl); + let call = superSetCookie.call(this, cookie, currentUrl, options, callback); + // 根据瑞树6 cookie 特性 截取 `enable_XXXXXXXXXXXX=true` XXXXXXXX 为即将生成的 cookie key + if (generateCookieKey != null && cookie.includes(generateCookieKey)) { + window[uuid] = true + console.debug('匹配---->', cookie) + } + let match = cookie.match(/enable_(.*?)=true/); + if (match) { + generateCookieKey = match[1]; + console.debug('设置 匹配---->', generateCookieKey) + } + return call; + }; + + // ------------------------------------------------ 实例化浏览器 ----------------------------------------------------- + browser(window, 'chrome'); + // 加载js + let js = await JsUtil.loadJs(window.document, areaName, cookie); + console.log(`${uuid};js 加载长度--->`, js.length) + + + // 执行 js + let script = new Script(js); + let internalVMContext = dom.getInternalVMContext(); + script.runInContext(internalVMContext, {timeout: 1000}); + + // 等待 cookie 被设置 + for (let i = 0; i < 10; i++) { + if (window[uuid]) { + break; + } + await TimeUtil.sleep(100) + } + // 获取cookie + let resCookie = cookieJar.getCookieStringSync(baseUrl); + // 关闭 + dom.window.close() + return resCookie; + } + + // 将 cookie 转为 list + CookieStr2List(cookies) { + let list = [] + for (let cookie of cookies.trim().split("; ")) { + list.push(cookie); + } + return list + } + + + /** + * 方案1 + * 利用rs特性 js加载完成后会刷新页面 + * 利用 window.onbeforeunload 判断页面是否执行完毕 + * @param window + * @param cookieJar + * @param uuid + * @returns {Promise<*|null>} + */ + scheme1_before(window, cookieJar, uuid) { + window.onbeforeunload = async (url) => { + let baseUrl = new URL(url).origin; + const cookies = cookieJar.getCookieStringSync(baseUrl); + console.debug(`${url} 页面回调生成cookie:`, cookies); + this.store.set(uuid, cookies) + // window.close(); + } + } + + /** + * 方案1 + * @param window + * @param cookieJar + * @param uuid + * @returns {Promise<*|null>} + */ + async scheme1_after(window, cookieJar, uuid) { + // 等待 onbeforeunload 钩子触发后的回掉 + let val = await this.store.waitGetAndDelete(uuid, 100, 10) + if (val != null) { + return val; + } + return null; + } + + + /** + * 监听cookie出现指定cookie + * @param window + * @param cookieJar + * @param uuid + * @returns {Promise} + */ + scheme2_before(window, cookieJar, uuid) { + // window[uuid] = false; + const superSetCookie = cookieJar.setCookie; + // 设置 setCookie 代理 + cookieJar.setCookie = function (cookie, currentUrl, options, callback) { + console.log(`${uuid};正在设置 Cookie:`, cookie, currentUrl); + return superSetCookie.call(this, cookie, currentUrl, options, callback); + // let cookieStringSync = super.getCookieStringSync(); + // console.log(cookieStringSync) + // if (cookie.includes(key)) { + // // 设置标志可取标志 + // window[uuid] = true + // } + // return call; + }; + } + + /** + * 方案2 + * @param window + * @param cookieJar + * @param key + * @param uuid + * @returns {Promise} + */ + async scheme2_after(window, cookieJar, key, uuid) { + for (let i = 0; i < 10; i++) { + let cookieStringSync = cookieJar.getCookieStringSync(); + if (cookieStringSync.includes(key)) { + return cookieStringSync; + } + await TimeUtil.sleep(100) + } + return null; + } + + /** + * 方案3 根据cookie现有的数量判断 + * @param window + * @param cookieJar + * @param baseUrl + * @param uuid + */ + scheme3_before(window, cookieJar, baseUrl, uuid) { + const initCookie = cookieJar.getCookieStringSync(baseUrl); + window[uuid + 'CookieSize'] = initCookie != null ? initCookie.trim().split("; ").length : 0; + } + + /** + * 方案3 + * @param window + * @param cookieJar + * @param baseUrl + * @param uuid + * @returns {Promise} + */ + async scheme3_after(window, cookieJar, baseUrl, uuid) { + let initCookieLength = window[uuid + 'CookieSize'] + for (let i = 0; i < 10; i++) { + let cookieStringSync = cookieJar.getCookieStringSync(baseUrl); + let cookies = cookieStringSync != null ? cookieStringSync.trim().split("; ").length : 0; + if (cookies > initCookieLength) { + return cookieStringSync; + } + await TimeUtil.sleep(100) + } + return null; + } +} + +module.exports = Rs6Service \ No newline at end of file diff --git a/test/rs6/index.js b/test/rs6/index.js index 643cbe8..8c3536a 100644 --- a/test/rs6/index.js +++ b/test/rs6/index.js @@ -1,151 +1,151 @@ -const express = require('express') -const path = require('path') -const fs = require('fs') -const app = express() -const PORT = 3000 - -// process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" -const {jsdomFromText, jsdomFromUrl, browser} = require('sdenv'); -const {Script} = require("vm"); - - -const baseUrl = "https://etax.hebei.chinatax.gov.cn:8443/" - -const store = new Map(); - -const files = { - html: path.resolve('../public/hubei/index.html'), - js: path.resolve('../public/hubei/5PXGXoOF7eGJ.ed63b8f.js'), - ts: path.resolve('../public/hubei/ts.json'), -} - -function getFile(name) { - const filepath = files[name]; - if (!filepath) throw new Error(`getFile: ${name}错误`); - if (!fs.existsSync(filepath)) throw new Error(`文件${filepath}不存在,请使用rs-reverse工具先获取文件`); - return fs.readFileSync(filepath); -} - -async function loadPages(key) { - const htmlText = getFile('html'); - const jsText = getFile('js'); - let tsText = getFile('ts'); - let get = `${baseUrl}`; - const [jsDom, cookieJar] = jsdomFromText({ - url: get, - referrer: get, - contentType: "text/html", - runScripts: "dangerously",//dangerously启用在页面内执行js,outside-only在外部执行js:window.eval() - }) - const dom = jsDom(htmlText); - window = dom.window - window.$_ts = JSON.parse(tsText.toString()); - window.onbeforeunload = async (url) => { - const cookies = cookieJar.getCookieStringSync(baseUrl); - console.debug('生成cookie:', cookies); - store.set(key, cookies) - // window.close(); - } - browser(window, 'chrome'); - - new Script(jsText.toString()).runInContext(dom.getInternalVMContext()); - - return cookieJar; -} - -let sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - - -function action(key, url) { - return new Promise(async (resolve, reject) => { - let cookieJar = await loadPages(key, url); - // for (let i = 0; i < 100; i++) { - await sleep(1000) - let cookieStringSync = cookieJar.getCookieStringSync(baseUrl); - let val = store.get(key); - // console.log(val) - console.log(cookieStringSync) - // 尝试访问 - let response = await fetch(baseUrl, { - "headers": { - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "accept-language": "zh-CN,zh;q=0.9", - "cache-control": "no-cache", - "pragma": "no-cache", - "priority": "u=0, i", - "sec-ch-ua": "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"Linux\"", - "sec-fetch-dest": "document", - "sec-fetch-mode": "navigate", - "sec-fetch-site": "none", - "sec-fetch-user": "?1", - "upgrade-insecure-requests": "1" - }, - "referrerPolicy": "strict-origin-when-cross-origin", - "body": null, - "method": "GET" - }); - console.log('11111111111', response.headers.get('set-cookie')); - - if (cookieStringSync !== undefined) { - return resolve(cookieStringSync) - } - // } - reject('未获取到cookie') - }) -} - -action("111111", baseUrl) - -app.get('/getCookie', async (req, res) => { - let traceId = req.query['traceId']; - if (traceId === undefined) { - return res.send('error') - } - let url = req.query['url']; - try { - let ac = await action(traceId, url); - return res.send(ac) - } catch (e) { - return res.send(e) - } -}) - -// -// fetch("https://tpass.hebei.chinatax.gov.cn:8443/sys-api/v1.0/auth/oauth2/getPublicKey", { -// "headers": { -// "accept": "application/json, text/plain, */*", -// "accept-language": "zh-CN,zh;q=0.9", -// "authorization": "", -// "cache-control": "no-cache", -// "content-type": "application/json", -// "deviceidentyno": "wrhX86TArZj82EUurHJWVBktiBVKERpy", -// "huid": "", -// "pragma": "no-cache", -// "priority": "u=1, i", -// "sec-ch-ua": "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"", -// "sec-ch-ua-mobile": "?0", -// "sec-ch-ua-platform": "\"Linux\"", -// "sec-fetch-dest": "empty", -// "sec-fetch-mode": "cors", -// "sec-fetch-site": "same-origin", -// "x-app-clientid": "", -// "x-lang-id": "null", -// "x-nature-ip": "", -// "x-sm4-info": "0", -// "x-temp-info": "fffe092bceb04d32915d41c2634ed9ff", -// "x-ticket-id": "null" -// }, -// "referrer": "https://tpass.hebei.chinatax.gov.cn:8443/", -// "referrerPolicy": "strict-origin-when-cross-origin", -// "body": "{\"zipCode\":\"0\",\"encryptCode\":\"0\",\"datagram\":\"{}\",\"timestamp\":\"20240828150426\",\"access_token\":\"\",\"signtype\":\"HMacSHA256\",\"signature\":\"67848659b891af24ea9c2706e6fccbf03c2448666b719c00a49534dc536500fc\"}", -// "method": "POST", -// "mode": "cors", -// "credentials": "include" -// }); - - -// app.listen(PORT, () => { -// console.log(`app is running on PORT ${PORT}`) +// const express = require('express') +// const path = require('path') +// const fs = require('fs') +// const app = express() +// const PORT = 3000 +// +// // process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" +// const {jsdomFromText, jsdomFromUrl, browser} = require('sdenv'); +// const {Script} = require("vm"); +// +// +// const baseUrl = "https://etax.hebei.chinatax.gov.cn:8443/" +// +// const store = new Map(); +// +// const files = { +// html: path.resolve('../public/hubei/index.html'), +// js: path.resolve('../public/hubei/5PXGXoOF7eGJ.ed63b8f.js'), +// ts: path.resolve('../public/hubei/ts.json'), +// } +// +// function getFile(name) { +// const filepath = files[name]; +// if (!filepath) throw new Error(`getFile: ${name}错误`); +// if (!fs.existsSync(filepath)) throw new Error(`文件${filepath}不存在,请使用rs-reverse工具先获取文件`); +// return fs.readFileSync(filepath); +// } +// +// async function loadPages(key) { +// const htmlText = getFile('html'); +// const jsText = getFile('js'); +// let tsText = getFile('ts'); +// let get = `${baseUrl}`; +// const [jsDom, cookieJar] = jsdomFromText({ +// url: get, +// referrer: get, +// contentType: "text/html", +// runScripts: "dangerously",//dangerously启用在页面内执行js,outside-only在外部执行js:window.eval() +// }) +// const dom = jsDom(htmlText); +// window = dom.window +// window.$_ts = JSON.parse(tsText.toString()); +// window.onbeforeunload = async (url) => { +// const cookies = cookieJar.getCookieStringSync(baseUrl); +// console.debug('生成cookie:', cookies); +// store.set(key, cookies) +// // window.close(); +// } +// browser(window, 'chrome'); +// +// new Script(jsText.toString()).runInContext(dom.getInternalVMContext()); +// +// return cookieJar; +// } +// +// let sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); +// +// +// function action(key, url) { +// return new Promise(async (resolve, reject) => { +// let cookieJar = await loadPages(key, url); +// // for (let i = 0; i < 100; i++) { +// await sleep(1000) +// let cookieStringSync = cookieJar.getCookieStringSync(baseUrl); +// let val = store.get(key); +// // console.log(val) +// console.log(cookieStringSync) +// // 尝试访问 +// let response = await fetch(baseUrl, { +// "headers": { +// "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", +// "accept-language": "zh-CN,zh;q=0.9", +// "cache-control": "no-cache", +// "pragma": "no-cache", +// "priority": "u=0, i", +// "sec-ch-ua": "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"", +// "sec-ch-ua-mobile": "?0", +// "sec-ch-ua-platform": "\"Linux\"", +// "sec-fetch-dest": "document", +// "sec-fetch-mode": "navigate", +// "sec-fetch-site": "none", +// "sec-fetch-user": "?1", +// "upgrade-insecure-requests": "1" +// }, +// "referrerPolicy": "strict-origin-when-cross-origin", +// "body": null, +// "method": "GET" +// }); +// console.log('11111111111', response.headers.get('set-cookie')); +// +// if (cookieStringSync !== undefined) { +// return resolve(cookieStringSync) +// } +// // } +// reject('未获取到cookie') +// }) +// } +// +// action("111111", baseUrl) +// +// app.get('/getCookie', async (req, res) => { +// let traceId = req.query['traceId']; +// if (traceId === undefined) { +// return res.send('error') +// } +// let url = req.query['url']; +// try { +// let ac = await action(traceId, url); +// return res.send(ac) +// } catch (e) { +// return res.send(e) +// } // }) +// +// // +// // fetch("https://tpass.hebei.chinatax.gov.cn:8443/sys-api/v1.0/auth/oauth2/getPublicKey", { +// // "headers": { +// // "accept": "application/json, text/plain, */*", +// // "accept-language": "zh-CN,zh;q=0.9", +// // "authorization": "", +// // "cache-control": "no-cache", +// // "content-type": "application/json", +// // "deviceidentyno": "wrhX86TArZj82EUurHJWVBktiBVKERpy", +// // "huid": "", +// // "pragma": "no-cache", +// // "priority": "u=1, i", +// // "sec-ch-ua": "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"", +// // "sec-ch-ua-mobile": "?0", +// // "sec-ch-ua-platform": "\"Linux\"", +// // "sec-fetch-dest": "empty", +// // "sec-fetch-mode": "cors", +// // "sec-fetch-site": "same-origin", +// // "x-app-clientid": "", +// // "x-lang-id": "null", +// // "x-nature-ip": "", +// // "x-sm4-info": "0", +// // "x-temp-info": "fffe092bceb04d32915d41c2634ed9ff", +// // "x-ticket-id": "null" +// // }, +// // "referrer": "https://tpass.hebei.chinatax.gov.cn:8443/", +// // "referrerPolicy": "strict-origin-when-cross-origin", +// // "body": "{\"zipCode\":\"0\",\"encryptCode\":\"0\",\"datagram\":\"{}\",\"timestamp\":\"20240828150426\",\"access_token\":\"\",\"signtype\":\"HMacSHA256\",\"signature\":\"67848659b891af24ea9c2706e6fccbf03c2448666b719c00a49534dc536500fc\"}", +// // "method": "POST", +// // "mode": "cors", +// // "credentials": "include" +// // }); +// +// +// // app.listen(PORT, () => { +// // console.log(`app is running on PORT ${PORT}`) +// // }) diff --git a/utils/TimeUtil.js b/utils/TimeUtil.js new file mode 100644 index 0000000..eabaf6e --- /dev/null +++ b/utils/TimeUtil.js @@ -0,0 +1,9 @@ +class TimeUtil { + static sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + + static *sleepSync(ms){ + return yield new Promise(resolve => setTimeout(resolve, ms)) + } +} + +module.exports = TimeUtil; \ No newline at end of file