js补环境之补指纹

       补环境不得关键之处是补canvas2DFP和canvas3DFP以及一些插件,一些特定的浏览器特征值。以下是某验的检测函数的一部分:

"$_BGHf": function () {
            function s(e) {
                if (e) {
                    if (1 === e["nodeType"]) {
                        var t = (e["nodeName"] || "")["toUpperCase"]();
                        -1 < new ce(f["$_BIIL"]["concat"](f["$_BIJJ"]))["$_EHu"](t) && (i[t] ? i[t] += 1 : i[t] = 1);
                    }
                    for (var n = e["childNodes"], r = 0, o = n["length"]; r < o; r += 1) 
                        s(n[r]);
                }
            }
            var e = window,
                t = e["screen"],
                p = e["document"],
                h = e["navigator"],
                n = p["documentElement"],
                f = this,
                i = {};
            s(p);
            var r = n["textContent"] || n["innerText"];
            i["textLength"] = r["length"];
            try {
                var o = n["innerHTML"];
                i["HTMLLength"] = o["length"];
            } catch (g) {}
            i["documentMode"] = p["documentMode"] || p["compatMode"], 
            i["browserLanguage"] = h["language"] || h["userLanguage"], 
            i["browserLanguages"] = h["languages"] && h["languages"]["join"](","), 
            i["systemLanguage"] = h["systemLanguage"], 
            i["devicePixelRatio"] = e["devicePixelRatio"], 
            i["colorDepth"] = t["colorDepth"], 
            i["userAgent"] = h["userAgent"], 
            i["cookieEnabled"] = f["$_BIGh"](h["cookieEnabled"]), 
            i["netEnabled"] = f["$_BIGh"](h["onLine"]), 
            i["innerWidth"] = e["innerWidth"], 
            i["innerHeight"] = e["innerHeight"];
            try {
                i["outerWidth"] = e["outerWidth"], i["outerHeight"] = e["outerHeight"];
            } catch (g) {
                i["outerWidth"] = f["$_BIFp"], i["outerHeight"] = f["$_BIFp"];
            }
            i["screenWidth"] = t["width"], 
            i["screenHeight"] = t["height"], 
            i["screenAvailWidth"] = t["availWidth"], 
            i["screenAvailHeight"] = t["availHeight"], 
            i["screenLeft"] = t["left"] || e["screenLeft"], 
            i["screenTop"] = t["top"] || e["screenTop"], 
            i["screenAvailLeft"] = t["availLeft"], 
            i["screenAvailTop"] = t["availTop"];
            try {
                i["localStorageEnabled"] = f["$_BIGh"](e["localStorage"]);
            } catch (g) {
                i["localStorageEnabled"] = f["$_BIFp"];
            }    
            try {
                i["sessionStorageEnabled"] = f["$_BIGh"](e["sessionStorage"]);
            } catch (g) {
                i["sessionStorageEnabled"] = f["$_BIFp"];
            }    
            return i["indexedDBEnabled"] = f["$_BIGh"](e["indexedDB"]), 
            i["CPUClass"] = h["cpuClass"], 
            i["platform"] = h["platform"], 
            i["doNotTrack"] = f["$_BIGh"](h["doNotTrack"]), 
            i["timezone"] = new Date()["getTimezoneOffset"]() / 60, 
            i["canvas2DFP"] = function () {
                var e = p["createElement"]("canvas"),
                t = e["getContext"] && e["getContext"]("2d");
                if (t) {
                    var n = [];
                    return e["width"] = 2e3, 
                           e["height"] = 200, 
                           e["style"]["display"] = "inline", 
                           t["rect"](0, 0, 11, 11), 
                           t["rect"](3, 3, 6, 6), 
                           n["push"]("canvas winding:" + (!1 === t["isPointInPath"](5, 5, "evenodd") ? "yes" : "no")), 
                           t["textBaseline"] = "alphabetic", 
                           t["fillStyle"] = "#f60", 
                           t["fillRect"](125, 1, 62, 20), 
                           t["fillStyle"] = "#069", 
                           t["font"] = "11pt Arial", 
                           t["fillText"]("Cwm fjordbank glyphs vext quiz, \uD83D\uDE03", 2, 15), 
                           t["fillStyle"] = "rgba(102, 204, 0, 0.7)", 
                           t["font"] = "18pt Arial", 
                           t["fillText"]("Cwm fjordbank glyphs vext quiz, \uD83D\uDE03", 4, 45), 
                           t["globalCompositeOperation"] = "multiply", 
                           t["fillStyle"] = "rgb(255,0,255)", 
                           t["beginPath"](), 
                           t["arc"](52, 50, 50, 0, 2 * Math["PI"], !0), 
                           t["closePath"](), 
                           t["fill"](), 
                           t["fillStyle"] = "rgb(0,255,255)", 
                           t["beginPath"](), 
                           t["arc"](100, 50, 50, 0, 2 * Math["PI"], !0), 
                           t["closePath"](), 
                           t["fill"](), 
                           t["fillStyle"] = "rgb(255,255,0)", 
                           t["beginPath"](), 
                           t["arc"](75, 100, 50, 0, 2 * Math["PI"], !0), 
                           t["closePath"](), 
                           t["fill"](), 
                           t["fillStyle"] = "rgb(255,0,255)", 
                           t["arc"](75, 75, 75, 0, 2 * Math["PI"], !0), 
                           t["arc"](75, 75, 25, 0, 2 * Math["PI"], !0), 
                           t["fill"]("evenodd"), 
                           n["push"]("canvas fp:" + e["toDataURL"]()), 
                           V(n["join"]("~"));
                }
                return f["$_BIFp"];
            }(), 
            i["canvas3DFP"] = function () {    
                try {
                    if (/\(i[^;]+;( U;)? CPU.+Mac OS X/["test"](h["userAgent"])) return f["$_BIFp"];
                    var e = p["createElement"]("canvas"),
                    t = e["getContext"] && (e["getContext"]("webgl") || e["getContext"]("experimental-webgl"));

                if (t) {
                  var r = [],
                      o = t["createBuffer"]();
                  t["bindBuffer"](t["ARRAY_BUFFER"], o);
                  var i = new Float32Array([-.2, -.9, 0, .4, -.26, 0, 0, .732134444, 0]);
                  t["bufferData"](t["ARRAY_BUFFER"], i, t["STATIC_DRAW"]), o["itemSize"] = 3, o["numItems"] = 3;
                  var s = t["createProgram"](),
                      a = t["createShader"](t["VERTEX_SHADER"]);
                  t["shaderSource"](a, "attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}"), t["compileShader"](a);
                  var c = t["createShader"](t["FRAGMENT_SHADER"]);
                  return t["shaderSource"](c, "precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}"), t["compileShader"](c), t["attachShader"](s, a), t["attachShader"](s, c), t["linkProgram"](s), t["useProgram"](s), s["vertexPosAttrib"] = t["getAttribLocation"](s, "attrVertex"), s["offsetUniform"] = t["getUniformLocation"](s, "uniformOffset"), t["enableVertexAttribArray"](s["vertexPosArray"]), t["vertexAttribPointer"](s["vertexPosAttrib"], o["itemSize"], t["FLOAT"], !1, 0, 0), t["uniform2f"](s["offsetUniform"], 1, 1), t["drawArrays"](t["TRIANGLE_STRIP"], 0, o["numItems"]), null != t["canvas"] && r["push"](t["canvas"]["toDataURL"]()), r["push"]("extensions:" + t["getSupportedExtensions"]()["join"](";")), r["push"]("webgl aliased line width range:" + n(t["getParameter"](t["ALIASED_LINE_WIDTH_RANGE"]))), r["push"]("webgl aliased point size range:" + n(t["getParameter"](t["ALIASED_POINT_SIZE_RANGE"]))), r["push"]("webgl alpha bits:" + t["getParameter"](t["ALPHA_BITS"])), r["push"]("webgl antialiasing:" + (t["getContextAttributes"]()["antialias"] ? "yes" : "no")), r["push"]("webgl blue bits:" + t["getParameter"](t["BLUE_BITS"])), r["push"]("webgl depth bits:" + t["getParameter"](t["DEPTH_BITS"])), r["push"]("webgl green bits:" + t["getParameter"](t["GREEN_BITS"])), r["push"]("webgl max anisotropy:" + ((u = (_ = t)["getExtension"]("EXT_texture_filter_anisotropic") || _["getExtension"]("WEBKIT_EXT_texture_filter_anisotropic") || _["getExtension"]("MOZ_EXT_texture_filter_anisotropic")) ? (0 === (l = _["getParameter"](u["MAX_TEXTURE_MAX_ANISOTROPY_EXT"])) && (l = 2), l) : null)), r["push"]("webgl max combined texture image units:" + t["getParameter"](t["MAX_COMBINED_TEXTURE_IMAGE_UNITS"])), r["push"]("webgl max cube map texture size:" + t["getParameter"](t["MAX_CUBE_MAP_TEXTURE_SIZE"])), r["push"]("webgl max fragment uniform vectors:" + t["getParameter"](t["MAX_FRAGMENT_UNIFORM_VECTORS"])), r["push"]("webgl max render buffer size:" + t["getParameter"](t["MAX_RENDERBUFFER_SIZE"])), r["push"]("webgl max texture image units:" + t["getParameter"](t["MAX_TEXTURE_IMAGE_UNITS"])), r["push"]("webgl max texture size:" + t["getParameter"](t["MAX_TEXTURE_SIZE"])), r["push"]("webgl max varying vectors:" + t["getParameter"](t["MAX_VARYING_VECTORS"])), r["push"]("webgl max vertex attribs:" + t["getParameter"](t["MAX_VERTEX_ATTRIBS"])), r["push"]("webgl max vertex texture image units:" + t["getParameter"](t["MAX_VERTEX_TEXTURE_IMAGE_UNITS"])), r["push"]("webgl max vertex uniform vectors:" + t["getParameter"](t["MAX_VERTEX_UNIFORM_VECTORS"])), r["push"]("webgl max viewport dims:" + n(t["getParameter"](t["MAX_VIEWPORT_DIMS"]))), r["push"]("webgl red bits:" + t["getParameter"](t["RED_BITS"])), r["push"]("webgl renderer:" + t["getParameter"](t["RENDERER"])), r["push"]("webgl shading language version:" + t["getParameter"](t["SHADING_LANGUAGE_VERSION"])), r["push"]("webgl stencil bits:" + t["getParameter"](t["STENCIL_BITS"])), r["push"]("webgl vendor:" + t["getParameter"](t["VENDOR"])), r["push"]("webgl version:" + t["getParameter"](t["VERSION"])), t["getShaderPrecisionFormat"] ? (r["push"]("webgl vertex shader high float precision:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["HIGH_FLOAT"])["precision"]), r["push"]("webgl vertex shader high float precision rangeMin:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["HIGH_FLOAT"])["rangeMin"]), r["push"]("webgl vertex shader high float precision rangeMax:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["HIGH_FLOAT"])["rangeMax"]), r["push"]("webgl vertex shader medium float precision:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["MEDIUM_FLOAT"])["precision"]), r["push"]("webgl vertex shader medium float precision rangeMin:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["MEDIUM_FLOAT"])["rangeMin"]), r["push"]("webgl vertex shader medium float precision rangeMax:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["MEDIUM_FLOAT"])["rangeMax"]), r["push"]("webgl vertex shader low float precision:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["LOW_FLOAT"])["precision"]), r["push"]("webgl vertex shader low float precision rangeMin:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["LOW_FLOAT"])["rangeMin"]), r["push"]("webgl vertex shader low float precision rangeMax:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["LOW_FLOAT"])["rangeMax"]), r["push"]("webgl fragment shader high float precision:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["HIGH_FLOAT"])["precision"]), r["push"]("webgl fragment shader high float precision rangeMin:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["HIGH_FLOAT"])["rangeMin"]), r["push"]("webgl fragment shader high float precision rangeMax:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["HIGH_FLOAT"])["rangeMax"]), r["push"]("webgl fragment shader medium float precision:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["MEDIUM_FLOAT"])["precision"]), r["push"]("webgl fragment shader medium float precision rangeMin:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["MEDIUM_FLOAT"])["rangeMin"]), r["push"]("webgl fragment shader medium float precision rangeMax:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["MEDIUM_FLOAT"])["rangeMax"]), r["push"]("webgl fragment shader low float precision:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["LOW_FLOAT"])["precision"]), r["push"]("webgl fragment shader low float precision rangeMin:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["LOW_FLOAT"])["rangeMin"]), r["push"]("webgl fragment shader low float precision rangeMax:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["LOW_FLOAT"])["rangeMax"]), r["push"]("webgl vertex shader high int precision:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["HIGH_INT"])["precision"]), r["push"]("webgl vertex shader high int precision rangeMin:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["HIGH_INT"])["rangeMin"]), r["push"]("webgl vertex shader high int precision rangeMax:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["HIGH_INT"])["rangeMax"]), r["push"]("webgl vertex shader medium int precision:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["MEDIUM_INT"])["precision"]), r["push"]("webgl vertex shader medium int precision rangeMin:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["MEDIUM_INT"])["rangeMin"]), r["push"]("webgl vertex shader medium int precision rangeMax:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["MEDIUM_INT"])["rangeMax"]), r["push"]("webgl vertex shader low int precision:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["LOW_INT"])["precision"]), r["push"]("webgl vertex shader low int precision rangeMin:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["LOW_INT"])["rangeMin"]), r["push"]("webgl vertex shader low int precision rangeMax:" + t["getShaderPrecisionFormat"](t["VERTEX_SHADER"], t["LOW_INT"])["rangeMax"]), r["push"]("webgl fragment shader high int precision:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["HIGH_INT"])["precision"]), r["push"]("webgl fragment shader high int precision rangeMin:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["HIGH_INT"])["rangeMin"]), r["push"]("webgl fragment shader high int precision rangeMax:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["HIGH_INT"])["rangeMax"]), r["push"]("webgl fragment shader medium int precision:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["MEDIUM_INT"])["precision"]), r["push"]("webgl fragment shader medium int precision rangeMin:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["MEDIUM_INT"])["rangeMin"]), r["push"]("webgl fragment shader medium int precision rangeMax:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["MEDIUM_INT"])["rangeMax"]), r["push"]("webgl fragment shader low int precision:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["LOW_INT"])["precision"]), r["push"]("webgl fragment shader low int precision rangeMin:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["LOW_INT"])["rangeMin"]), r["push"]("webgl fragment shader low int precision rangeMax:" + t["getShaderPrecisionFormat"](t["FRAGMENT_SHADER"], t["LOW_INT"])["rangeMax"]), V(r["join"]("~"))) : V(r["join"]("~"));
                }

                return f["$_BIFp"];
              } catch (g) {
                return f["$_BIFp"];
              }

              var _, l, u;
            }(), i["plugins"] = function () {    
                  if (!h["plugins"]) return f["$_BIDk"];
                  for (var e = [], t = 0, n = 40 < h["plugins"]["length"] ? 40 : h["plugins"]["length"]; t < n; t += 1) {
                    var r = h["plugins"][t];
                    e["push"](r["filename"] && r["filename"]["replace"](/\s/g, ""));
                  }
                  return e["join"](",");
            }(), 
            i["maxTouchPoints"] = f["$_BIHw"](h["maxTouchPoints"]) ? f["$_BIHw"](h["msMaxTouchPoints"]) ? 0 : h["msMaxTouchPoints"] : h["maxTouchPoints"], 
            i["flashEnabled"] = f["$_BIHw"](e["swfobject"]) ? f["$_BIDk"] : f["$_BIGh"](e["swfobject"]["hasFlashPlayerVersion"] && e["swfobject"]["hasFlashPlayerVersion"]("9.0.0")), 
            i["javaEnabled"] = function () {
                try {
                    return f["$_BIHw"](h["javaEnabled"]) ? f["$_BIDk"] : f["$_BIGh"](h["javaEnabled"]());
                } catch (g) {
                    return f["$_BIDk"];
                }
            }(), 

            i["hardwareConcurrency"] = h["hardwareConcurrency"], 
            i["jsFonts"] = y || b || w ? 
            ["monospace", "sans-serif", "serif"]["join"](",") : 
            function () {    
                    function t(e) {
                        for (var t = !1, n = 0; n < l["length"]; n++) 
                            if (t = e[n]["offsetWidth"] !== r[l[n]] || e[n]["offsetHeight"] !== i[l[n]]) 
                                return t;
                        return t;
                    }
                    function h() {
                        var e = L["createElement"]("span");
                        return e["style"]["position"] = "absolute", e["style"]["left"] = "-9999px", e["style"]["fontSize"] = "72px", e["innerHTML"] = "mmmmmmmmmmlli", e;
                    }
                    var l = ["monospace", "sans-serif", "serif"],
                    u = ["Andale Mono", "Arial", "Arial Black", "Arial Hebrew", "Arial MT", "Arial Narrow", "Arial Rounded MT Bold", "Arial Unicode MS", "Bitstream Vera Sans Mono", "Book Antiqua", "Bookman Old Style", "Calibri", "Cambria", "Cambria Math", "Century", "Century Gothic", "Century Schoolbook", "Comic Sans", "Comic Sans MS", "Consolas", "Courier", "Courier New", "Garamond", "Geneva", "Georgia", "Helvetica", "Helvetica Neue", "Impact", "Lucida Bright", "Lucida Calligraphy", "Lucida Console", "Lucida Fax", "LUCIDA GRANDE", "Lucida Handwriting", "Lucida Sans", "Lucida Sans Typewriter", "Lucida Sans Unicode", "Microsoft Sans Serif", "Monaco", "Monotype Corsiva", "MS Gothic", "MS Outlook", "MS PGothic", "MS Reference Sans Serif", "MS Sans Serif", "MS Serif", "MYRIAD", "MYRIAD PRO", "Palatino", "Palatino Linotype", "Segoe Print", "Segoe Script", "Segoe UI", "Segoe UI Light", "Segoe UI Semibold", "Segoe UI Symbol", "Tahoma", "Times", "Times New Roman", "Times New Roman PS", "Trebuchet MS", "Verdana", "Wingdings", "Wingdings 2", "Wingdings 3"],
                    e = L["getElementsByTagName"]("body")[0];
                    if (!e) return l["push"]("Aria1"), l["join"](",");
                    var o = L["createElement"]("div"),
                        p = L["createElement"]("div"),
                        r = {},
                        i = {},
                        n = function () {
                              for (var e = [], t = 0, n = l["length"]; t < n; t++) {
                                  var r = h();
                                  
                                  r["style"]["fontFamily"] = l[t], o["appendChild"](r), e["push"](r);
                              }       
                           return e;
                        }();
                    e["appendChild"](o);
                n[1]["offsetWidth"]=732;
                n[1]["offsetHeight"]=95;
                for (var s = 0, a = l["length"]; s < a; s++) 
                    r[l[s]] = n[s]["offsetWidth"], i[l[s]] = n[s]["offsetHeight"];

                var c = function () {           
                    for (var e, t, n, r = {}, o = 0, i = u["length"]; o < i; o++) {
                        for (var s = [], a = 0, c = l["length"]; a < c; a++) {
                             var _ = (e = u[o], t = l[a], 
                              n = void 0, 
                              (n = h())["style"]["fontFamily"] = "'" + e + "'," + t, n);
                              p["appendChild"](_), s["push"](_);
                        }
                        r[u[o]] = s;
                    }
                    return r;
                }();
                e["appendChild"](p);
                for (var _ = [], f = 0, g = u["length"]; f < g; f++) 
                    t(c[u[f]]) && _["push"](u[f]["replace"](/\s/g, ""));
                _= ['Arial', 'ArialBlack', 'ArialNarrow', 'Calibri', 'Cambria', 'CambriaMath', 'ComicSansMS', 'Consolas', 'Courier', 'CourierNew', 'Georgia', 'Helvetica', 'Impact', 'LucidaConsole', 'LucidaSansUnicode', 'MicrosoftSansSerif', 'MSGothic', 'MSPGothic', 'MSSansSerif', 'MSSerif', 'PalatinoLinotype', 'SegoePrint', 'SegoeScript', 'SegoeUI', 'SegoeUILight', 'SegoeUISemibold', 'SegoeUISymbol', 'Tahoma', 'Times', 'TimesNewRoman', 'TrebuchetMS', 'Verdana', 'Wingdings'];
                var d = _["join"](",");
                return e["removeChild"](p), e["removeChild"](o), d;
            }(), 
            i["mediaDevices"] = f["$_BIDk"], 
            i;
      }

在不同浏览器中使用这个参数,就能得到固定的参数,生成环境的代码也可以参考这个来产生。

### 关于 qxVm 环境配置问题 qxVm 的环境配置通常涉及充缺失的浏览器原生对象和功能,以模拟真实的浏览器行为。以下是针对该问题的具体解决方案: #### 1. 充基础浏览器对象 根据描述,qxVm 缺少一些核心浏览器对象,例如 `XMLHttpRequest` 和 `Image`[^1]。可以通过引入 polyfill 或手动实现这些对象来解决问题。 对于 `XMLHttpRequest`,可以使用以下代码作为替代实现: ```javascript function XMLHttpRequest() { this.open = function(method, url) {}; this.send = function(data) {}; this.setRequestHeader = function(header, value) {}; this.getResponseHeader = function(header) { return null; }; } ``` 对于 `Image` 对象,则可以创建一个简单的占位类: ```javascript function Image(width, height) { this.src = ''; this.onload = null; this.onerror = null; } ``` #### 2. 使用 jsDom 动态 DOM 实现 如果需要更完整的 DOM 支持,推荐使用经过修改的 jsDom 框架[^2]。此框架能够提供接近真实浏览器的动态 DOM 渲染能力,并支持事件绑定和其他交互操作。 安装方法如下: ```bash npm install jsdom ``` 基本初始化代码示例: ```javascript const { JSDOM } = require('jsdom'); const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`, { runScripts: 'outside-only' }); global.window = dom.window; global.document = window.document; ``` #### 3. 针对特定需求环境变量 在某些场景下,还需要额外充其他环境参数,例如 `userAgent`、`canvas` 指纹、`webgl` 检测以及 `location.href` 等[^4]。具体实现方式如下: - **User-Agent 设置** ```javascript Object.defineProperty(navigator, '.userAgent', { get: () => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', }); ``` - **Canvas 指纹伪造** ```javascript HTMLCanvasElement.prototype.getContext = function(originalFn) { const ctx = originalFn.apply(this, arguments); ctx.webkitImageSmoothingEnabled = true; return ctx; }; ``` - **WebGL 参数调整** ```javascript Object.defineProperty(window.WebGLRenderingContext.prototype, 'getParameter', { value: function(parameter) { switch (parameter) { case this.UNMASKED_VENDOR_WEBGL: return 'NVIDIA Corporation'; case this.UNMASKED_RENDERER_WEBGL: return 'GeForce GTX 1080/PCIe/SSE2'; default: return originalGetParameter.call(this, parameter); } }, }); ``` #### 4. 调试与验证 为了确保所有必要的环境均已正确配置,在运行过程中应设置断点并逐步排查可能存在的问题。建议利用 Chrome DevTools 或 Node.js 内置调试工具进行深入分析。 --- ### 示例总结代码 综合以上内容,下面是一份完整的环境配置脚本模板: ```javascript // 初始化 jsDom const { JSDOM } = require('jsdom'); const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`, { runScripts: "outside-only" }); global.window = dom.window; global.document = window.document; // 充 User-Agent Object.defineProperty(navigator, 'userAgent', { get: () => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', }); // Canvas 指纹处理 HTMLCanvasElement.prototype.getContext = function(originalFn) { const ctx = originalFn.apply(this, arguments); ctx.webkitImageSmoothingEnabled = true; return ctx; }; // WebGL 参数覆盖 Object.defineProperty(window.WebGLRenderingContext.prototype, 'getParameter', { value: function(parameter) { switch (parameter) { case this.UNMASKED_VENDOR_WEBGL: return 'NVIDIA Corporation'; case this.UNMASKED_RENDERER_WEBGL: return 'GeForce GTX 1080/PCIe/SSE2'; default: return originalGetParameter.call(this, parameter); } }, }); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值