- // ==UserScript==
- // @name JS Cookie Monitor/Debugger Hook
- // @namespace https://github.com/CC11001100/crawler-js-hook-framework-public
- // @version 0.1
- // @description 用于监控js对cookie的修改,还可以在修改指定名称的cookie时进入断点
- // @author CC11001100
- // @match *://*/*
- // @run-at document-start
- // @grant none
- // ==/UserScript==
-
- (() => {
-
- // 用于监控cookie的声明周期
-
- const debuggerOnCookieChange = ["foobar-cookie-name"];
-
- // 使用document.cookie更新cookie,但是cookie新的值和原来的值一样,此时要不要忽略这个事件
- const ignoreUpdateButNotChanged = false;
-
- addCookieHook();
-
- function addCookieHook() {
- Object.defineProperty(document, "cookie", {
- get: () => {
- delete document.cookie;
- const currentDocumentCookie = document.cookie;
- addCookieHook();
- return currentDocumentCookie;
- },
- set: newValue => {
- cc11001100_onSetCookie(newValue);
- delete document.cookie;
- document.cookie = newValue;
- addCookieHook();
- },
- configurable: true
- });
- }
-
- /**
- * 这个方法的前缀起到命名空间的作用,等下调用栈追溯赋值cookie的代码时需要用这个名字作为终结标志
- *
- * @param newValue
- */
- function cc11001100_onSetCookie(newValue) {
- const cookiePair = parseSetCookie(newValue);
-
- // 如果过期时间为当前时间之前,则为删除
- if (new Date().getTime() >= cookiePair.expires) {
- onDeleteCookie(cookiePair.name);
- return;
- }
- const currentCookieMap = getCurrentCookieMap();
- // 如果之前已经存在,则是修改
- if (currentCookieMap.has(cookiePair.name)) {
- onCookieUpdate(cookiePair.name, currentCookieMap.get(cookiePair.name).value, cookiePair.value);
- return;
- }
-
- // 否则则为添加
- onCookieAdd(cookiePair.name, cookiePair.value);
- }
-
- /**
- * 删除cookie
- *
- * @param cookieName
- */
- function onDeleteCookie(cookieName) {
- const valueStyle = "color: black; background: #E50000; font-size: 13px; font-weight: bold;";
- const normalStyle = "color: black; background: #FF6766; font-size: 13px;";
-
- const message = [
-
- normalStyle,
- now(),
-
- normalStyle,
- "JS Cookie Monitor: ",
-
- normalStyle,
- "delete cookie, cookieName = ",
-
- valueStyle,
- `${cookieName}`,
-
- normalStyle,
- `, code location = ${getCodeLocation()}`
- ];
- console.log(genFormatArray(message), ...message);
-
- if (debuggerOnCookieChange.indexOf(cookieName) !== -1) {
- debugger;
- }
- }
-
- /**
- * 更新cookie
- *
- * @param cookieName
- * @param oldCookieValue
- * @param newCookieValue
- */
- function onCookieUpdate(cookieName, oldCookieValue, newCookieValue) {
-
- const cookieValueChanged = oldCookieValue !== newCookieValue;
-
- if (ignoreUpdateButNotChanged && !cookieValueChanged) {
- return;
- }
-
- const valueStyle = "color: black; background: #FE9900; font-size: 13px; font-weight: bold;";
- const normalStyle = "color: black; background: #FFCC00; font-size: 13px;";
-
- const message = [
-
- normalStyle,
- now(),
-
- normalStyle,
- "JS Cookie Monitor: ",
-
- normalStyle,
- "update cookie, name = ",
-
- valueStyle,
- `${cookieName}`,
-
- normalStyle,
- `, oldValue = `,
-
- valueStyle,
- `${oldCookieValue}`,
-
- normalStyle,
- `, newValue = `,
-
- valueStyle,
- `${newCookieValue}`,
-
- normalStyle,
- `, value changed =`,
-
- valueStyle,
- `${cookieValueChanged}`,
-
- normalStyle,
- `, code location = ${getCodeLocation()}`
- ];
- console.log(genFormatArray(message), ...message);
-
- if (debuggerOnCookieChange.indexOf(cookieName) !== -1) {
- debugger;
- }
- }
-
- /**
- * 添加cookie
- *
- * @param cookieName
- * @param cookieValue
- */
- function onCookieAdd(cookieName, cookieValue) {
- const valueStyle = "color: black; background: #669934; font-size: 13px; font-weight: bold;";
- const normalStyle = "color: black; background: #65CC66; font-size: 13px;";
-
- const message = [
-
- normalStyle,
- now(),
-
- normalStyle,
- "JS Cookie Monitor: ",
-
- normalStyle,
- "add cookie, ",
-
- valueStyle,
- `${cookieName}`,
-
- normalStyle,
- " = ",
-
- valueStyle,
- `${cookieValue}`,
-
- normalStyle,
- `, code location = ${getCodeLocation()}`
- ];
- console.log(genFormatArray(message), ...message);
-
- if (debuggerOnCookieChange.indexOf(cookieName) !== -1) {
- debugger;
- }
- }
-
- function now() {
- return "[" + new Date(new Date().getTime() + 1000 * 60 * 60 * 8).toJSON().replace("T", " ").replace("Z", " ") + "] ";
- }
-
- function genFormatArray(messageAndStyleArray) {
- const formatArray = [];
- for (let i = 0, end = messageAndStyleArray.length / 2; i < end; i++) {
- formatArray.push("%c%s");
- }
- return formatArray.join("");
- }
-
- function getCodeLocation() {
- const callstack = new Error().stack.split("\n");
- while (callstack.length && callstack[0].indexOf("cc11001100") === -1) {
- callstack.shift();
- }
- callstack.shift();
- callstack.shift();
-
- return callstack[0].trim();
- }
-
- /**
- * 将本次设置cookie的字符串解析为容易处理的形式
- *
- * @param cookieString
- * @returns {CookiePair}
- */
- function parseSetCookie(cookieString) {
- // uuid_tt_dd=10_37476713480-1609821005397-659114; Expires=Thu, 01 Jan 2025 00:00:00 GMT; Path=/; Domain=.csdn.net;
- const cookieStringSplit = cookieString.split(";");
- const cookieNameValueArray = cookieStringSplit[0].split("=");
- const cookieName = decodeURIComponent(cookieNameValueArray[0].trim());
- const cookieValue = cookieNameValueArray.length > 1 ? decodeURIComponent(cookieNameValueArray[1].trim()) : "";
- const map = new Map();
- for (let i = 1; i < cookieStringSplit.length; i++) {
- const ss = cookieStringSplit[i].split("=", 2);
- const key = ss[0].trim().toLowerCase();
- const value = ss.length > 1 ? ss[1].trim() : "";
- map.set(key, value);
- }
- const expires = map.get("expires");
- return new CookiePair(cookieName, cookieValue, new Date(expires).getTime())
- }
-
- /**
- * 获取当前所有已经设置的cookie
- *
- * @returns {Map<string, CookiePair>}
- */
- function getCurrentCookieMap() {
- const cookieMap = new Map();
- if (!document.cookie) {
- return cookieMap;
- }
- document.cookie.split(";").forEach(x => {
- const ss = x.split("=", 2);
- const key = decodeURIComponent(ss[0].trim());
- const value = ss.length > 1 ? decodeURIComponent(ss[1].trim()) : "";
- cookieMap.set(key, new CookiePair(key, value));
- });
- return cookieMap;
- }
-
- class CookiePair {
- constructor(name, value, expires) {
- this.name = name;
- this.value = value;
- this.expires = expires;
- }
- }
-
- })();