JavaScript补环境报错navigator is not defined几种解决方案

 更新时间:2026年06月10日 08:34:17   作者:周小董  
这篇文章主要介绍了JavaScript补环境报错navigator is not defined的几种解决方案,文中通过代码介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下

js补环境报错navigator is not defined

遇到 navigator is not defined 错误,通常是因为在 Node.js 环境中运行了浏览器端的代码。以下是几种解决方案:

1.使用 JSDOM(推荐)

const { JSDOM } = require('jsdom');

// 创建虚拟的浏览器环境
const dom = new JSDOM(`<!DOCTYPE html><html><body></body></html>`, {
  url: 'https://example.com',
  pretendToBeVisual: true,
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
});

// 将全局对象挂载到 global
global.window = dom.window;
global.document = window.document;
global.navigator = window.navigator;
global.location = window.location;

// 现在可以使用 navigator 了
console.log(navigator.userAgent);
console.log(navigator.platform);

2.简单的模拟补环境

如果只需要基本功能:

// 在代码开头添加这些全局变量
if (typeof global !== 'undefined') {
  // Node.js 环境
  global.navigator = {
    userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    platform: 'Win32',
    language: 'zh-CN',
    languages: ['zh-CN', 'zh'],
    cookieEnabled: true,
    webdriver: false,
    appVersion: '5.0 (Windows)',
    vendor: '',
    vendorSub: '',
    product: 'Gecko',
    productSub: '20030107',
    hardwareConcurrency: 8,
    
    // 常用属性
    plugins: [],
    mimeTypes: [],
    
    // 常用方法
    javaEnabled: () => false,
    sendBeacon: () => true
  };
}

3.使用 puppeteer-extra 插件补环境

安装相关包:

npm install puppeteer-extra puppeteer-extra-plugin-stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  
  // 设置 userAgent
  await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
  
  // 执行代码
  const result = await page.evaluate(() => {
    // 这里可以安全使用 navigator
    return {
      userAgent: navigator.userAgent,
      platform: navigator.platform
    };
  });
  
  console.log(result);
  await browser.close();
})();

4.完整的环境模拟类

创建一个环境模拟类:

class BrowserEnv {
  constructor() {
    this.setupGlobals();
  }
  
  setupGlobals() {
    if (typeof global !== 'undefined') {
      // 模拟 navigator
      global.navigator = {
        userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        platform: 'Win32',
        language: 'zh-CN',
        languages: ['zh-CN', 'zh'],
        cookieEnabled: true,
        webdriver: false,
        appVersion: '5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        vendor: 'Google Inc.',
        vendorSub: '',
        product: 'Gecko',
        productSub: '20030107',
        hardwareConcurrency: 12,
        maxTouchPoints: 0,
        onLine: true,
        
        // 模拟插件
        plugins: {
          length: 3,
          [0]: { name: 'Chrome PDF Plugin' },
          [1]: { name: 'Chrome PDF Viewer' },
          [2]: { name: 'Native Client' }
        },
        
        // 方法
        javaEnabled: function() { return false; },
        sendBeacon: function() { return true; }
      };
      
      // 模拟 window
      global.window = {
        navigator: global.navigator,
        document: {},
        location: {
          href: 'https://www.example.com',
          protocol: 'https:',
          host: 'www.example.com',
          hostname: 'www.example.com',
          port: '',
          pathname: '/',
          search: '',
          hash: '',
          origin: 'https://www.example.com'
        },
        screen: {
          width: 1920,
          height: 1080,
          availWidth: 1920,
          availHeight: 1040,
          colorDepth: 24,
          pixelDepth: 24
        }
      };
      
      // 模拟 document
      global.document = {
        characterSet: 'UTF-8',
        contentType: 'text/html',
        documentElement: {
          clientWidth: 1903,
          clientHeight: 969
        }
      };
    }
  }
  
  // 更新特定属性
  setUserAgent(ua) {
    if (global.navigator) {
      global.navigator.userAgent = ua;
    }
  }
}

// 使用
new BrowserEnv();
console.log(navigator.userAgent);

5.使用 vm2 沙箱环境

const { VM } = require('vm2');

const vm = new VM({
  sandbox: {
    navigator: {
      userAgent: 'Mozilla/5.0...',
      platform: 'Win32'
    },
    window: {
      navigator: this.navigator
    }
  }
});

// 在沙箱中运行代码
vm.run(`
  console.log(navigator.userAgent);
  // 你的代码
`);

使用建议

  1. 根据需求选择方案

    • 简单测试:用方案2
    • 网页爬虫/自动化:用方案3
    • 复杂环境模拟:用方案1或4
  2. 常见的需要补的属性

    // 这些属性常被网站检测
    navigator.webdriver  // 通常设为 false
    navigator.plugins.length  // 插件数量
    navigator.languages  // 语言设置
    
  3. 调试技巧

    // 检查缺少的属性
    try {
      // 你的代码
    } catch (e) {
      console.log('缺少属性:', e.message);
      // 根据错误信息补充对应属性
    }
    

选择哪种方案取决于你的具体需求。如果是做爬虫或逆向工程,建议使用 JSDOM 或 puppeteer 方案。

JS中怎么全局化一个函数

在 JavaScript 中,有多种方式可以全局化函数。以下是具体的方法:

1.在浏览器环境中

方法一:直接挂载到window对象

// 定义全局函数
window.myGlobalFunction = function() {
  console.log('这是全局函数');
  return 'Hello World';
};

// 直接调用(无需 window. 前缀)
myGlobalFunction();

方法二:使用var声明(旧方式)

// 在最外层使用 var 声明(不推荐在现代代码中使用)
var myGlobalFunction = function() {
  console.log('全局函数');
};

方法三:隐式全局(不推荐)

// 没有使用 var/let/const 声明(严格模式下会报错)
function myGlobalFunction() {
  console.log('隐式全局');
}

2.在 Node.js 环境中

方法一:挂载到global对象

// Node.js 环境中
global.myGlobalFunction = function() {
  console.log('Node.js 全局函数');
  return 'Node Global';
};

// 直接调用
myGlobalFunction();

方法二:使用globalThis(ES2020+)

// 跨环境兼容方案(浏览器和Node.js都适用)
globalThis.myGlobalFunction = function() {
  console.log('使用 globalThis');
  return 'Works everywhere';
};

// 调用
myGlobalFunction();

3.跨环境兼容的封装方法

方法一:检测环境并挂载

// 封装一个跨平台的全局函数设置器
function makeGlobal(funcName, func) {
  if (typeof window !== 'undefined') {
    // 浏览器环境
    window[funcName] = func;
  } else if (typeof global !== 'undefined') {
    // Node.js 环境
    global[funcName] = func;
  } else if (typeof globalThis !== 'undefined') {
    // 现代环境
    globalThis[funcName] = func;
  } else {
    // 其他环境
    this[funcName] = func;
  }
}

// 使用
makeGlobal('sayHello', function(name) {
  console.log(`Hello, ${name || 'World'}!`);
});

// 调用
sayHello('Alice');

方法二:自动检测并挂载

// 自动挂载到全局对象
(function(globalObject) {
  // 定义你的函数
  function calculateSum(a, b) {
    return a + b;
  }
  
  function formatDate(date) {
    return date.toISOString().split('T')[0];
  }
  
  // 挂载到全局
  globalObject.calculateSum = calculateSum;
  globalObject.formatDate = formatDate;
  
  // 如果需要,也可以挂载多个
  Object.assign(globalObject, {
    utils: {
      calculateSum,
      formatDate,
      multiply: (a, b) => a * b
    }
  });
})(
  typeof global !== 'undefined' ? global :
  typeof window !== 'undefined' ? window :
  typeof globalThis !== 'undefined' ? globalThis :
  this
);

// 调用
console.log(calculateSum(5, 3)); // 8
console.log(utils.multiply(4, 5)); // 20

4.模块化环境下的全局化

在 ES6 模块中:

// global-functions.js
const myFunctions = {
  greet: function(name) {
    return `Hello, ${name}!`;
  },
  add: function(a, b) {
    return a + b;
  }
};

// 挂载到全局
if (typeof window !== 'undefined') {
  window.appFunctions = myFunctions;
} else if (typeof global !== 'undefined') {
  global.appFunctions = myFunctions;
}

export default myFunctions;

5.创建全局命名空间(推荐)

为了避免污染全局命名空间,建议使用单一全局变量:

// 创建或使用现有的全局命名空间
if (!window.MyApp) {
  window.MyApp = {};
}

// 或者使用 globalThis
if (!globalThis.MyApp) {
  globalThis.MyApp = {};
}

// 向命名空间添加函数
MyApp.utils = {
  formatCurrency: function(amount) {
    return `$${amount.toFixed(2)}`;
  },
  generateId: function() {
    return 'id-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
  },
  validateEmail: function(email) {
    const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return re.test(email);
  }
};

// 使用
console.log(MyApp.utils.formatCurrency(19.99));
console.log(MyApp.utils.validateEmail('test@example.com'));

6.动态加载全局函数

// 动态加载函数到全局
function loadGlobalFunctions(functions) {
  const globalObj = globalThis || window || global;
  
  Object.keys(functions).forEach(key => {
    // 避免覆盖已有函数
    if (!globalObj[key]) {
      globalObj[key] = functions[key];
    } else {
      console.warn(`函数 ${key} 已存在,跳过`);
    }
  });
}

// 批量加载
loadGlobalFunctions({
  debounce: function(fn, delay) {
    let timer;
    return function(...args) {
      clearTimeout(timer);
      timer = setTimeout(() => fn.apply(this, args), delay);
    };
  },
  throttle: function(fn, limit) {
    let inThrottle;
    return function(...args) {
      if (!inThrottle) {
        fn.apply(this, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  }
});

// 使用
const search = debounce(function(query) {
  console.log('搜索:', query);
}, 300);

最佳实践建议

  1. 避免污染全局命名空间:尽量使用命名空间模式
  2. 使用 globalThis:兼容性最好的方式
  3. 检查是否存在:避免覆盖已有函数
  4. 考虑使用模块系统:现代前端开发推荐使用 ES6 模块
// 最推荐的实践
(function() {
  // 定义你的函数库
  const myLib = {
    // 各种工具函数
  };
  
  // 挂载到全局(如果需要)
  if (typeof globalThis !== 'undefined') {
    globalThis.myLib = myLib;
  }
})();

JS 补环境报错TypeError: Cannot read properties of undefined (reading ‘back’)

这个错误通常发生在JavaScript逆向工程中,当你尝试补环境时,缺少了必要的对象或属性。'back' 属性通常是某些特定API的一部分。以下是常见的原因和解决方案:

常见原因及解决方案

1.缺失 window.history.back() 方法

// 添加 history.back 方法
if (!window.history.back) {
    window.history.back = function() {
        console.log('history.back() called');
        // 可以返回一个Promise或具体值
        return Promise.resolve();
    };
}

2.缺失自定义对象或API的 back 方法

// 例如,对于某些SDK或API
if (window.someSDK && !window.someSDK.back) {
    window.someSDK.back = function() {
        console.log('someSDK.back() called');
        // 根据实际需求实现逻辑
        return {};
    };
}

3.更完整的 history 对象补环境

// 完整的 history 对象补全
window.history = window.history || {};
window.history.back = window.history.back || function() {
    console.log('[补环境] history.back() 被调用');
    return undefined;
};

window.history.forward = window.history.forward || function() {
    console.log('[补环境] history.forward() 被调用');
    return undefined;
};

window.history.go = window.history.go || function(num) {
    console.log(`[补环境] history.go(${num}) 被调用`);
    return undefined;
};

// 其他 history 属性
Object.defineProperties(window.history, {
    length: {
        get: function() {
            return 1; // 返回一个合理的值
        },
        configurable: true
    },
    state: {
        get: function() {
            return null;
        },
        configurable: true
    }
});

4.使用 Proxy 拦截属性访问

// 全局拦截 undefined 属性的访问
window = new Proxy(window, {
    get: function(target, property) {
        console.log(`[补环境] 访问 window.${property.toString()}`);
        
        // 如果属性不存在,返回一个函数或对象
        if (!(property in target)) {
            // 对于方法调用
            if (property === 'back' || property.endsWith('back')) {
                return function() {
                    console.log(`[补环境] ${property}() 被调用`);
                    return {};
                };
            }
            // 返回一个空对象,避免后续访问出错
            return {};
        }
        return target[property];
    }
});

// 对特定对象使用 Proxy
window.someObject = new Proxy({}, {
    get: function(target, property) {
        console.log(`[补环境] 访问 someObject.${property.toString()}`);
        
        if (!(property in target)) {
            if (property === 'back') {
                return function() {
                    console.log('[补环境] someObject.back() 被调用');
                    return {};
                };
            }
            // 自动创建嵌套对象
            target[property] = new Proxy({}, this);
            return target[property];
        }
        return target[property];
    }
});

5.完整的补环境框架示例

// 创建一个补环境配置对象
const envConfig = {
    // 需要补的 API 列表
    apis: {
        'history.back': {
            type: 'function',
            return: undefined,
            log: true
        },
        'someAPI.back': {
            type: 'function',
            return: { success: true },
            log: true
        },
        // 可以添加更多需要补的 API
    },
    
    // 自动补环境的方法
    patch: function() {
        for (const [path, config] of Object.entries(this.apis)) {
            const parts = path.split('.');
            let obj = window;
            
            // 创建嵌套对象结构
            for (let i = 0; i < parts.length - 1; i++) {
                if (!obj[parts[i]]) {
                    obj[parts[i]] = {};
                }
                obj = obj[parts[i]];
            }
            
            // 设置最终属性
            const lastPart = parts[parts.length - 1];
            if (!obj[lastPart]) {
                if (config.type === 'function') {
                    obj[lastPart] = function() {
                        if (config.log) {
                            console.log(`[补环境] ${path}() 被调用`);
                        }
                        return config.return;
                    };
                } else {
                    obj[lastPart] = config.value;
                }
            }
        }
    }
};

// 执行补环境
envConfig.patch();

6.调试技巧

// 启用详细调试
window.__debugEnv = true;

// 监控特定的属性访问
Object.defineProperty(window, 'someObject', {
    get: function() {
        console.trace('[补环境] window.someObject 被访问');
        return {
            back: function() {
                console.log('[补环境] someObject.back() 被调用');
                return {};
            }
        };
    },
    configurable: true
});

// 捕获所有错误
window.addEventListener('error', function(e) {
    console.log('[补环境] 捕获错误:', e.message);
    console.log('[补环境] 堆栈:', e.error.stack);
    // 可以在这里动态补环境
});

实际案例分析

案例1:某网站的 history.back

// 网站实际调用了 history.back()
if (!window.history) window.history = {};
if (!window.history.back) {
    window.history.back = function() {
        // 记录调用,便于调试
        console.log('[补环境] history.back() called at:', new Date().toISOString());
        // 阻止页面实际后退,只模拟行为
        return false;
    };
}

案例2:某SDK的 back 方法

// 假设 SDK 对象是 window.sdk
if (!window.sdk) window.sdk = {};
if (!window.sdk.back) {
    window.sdk.back = function(options) {
        console.log('[补环境] sdk.back() called with:', options);
        // 返回模拟的响应
        return {
            code: 0,
            message: 'success',
            data: {}
        };
    };
}

建议的调试步骤

  1. 先找出具体的调用栈

    // 在代码开头添加
    Error.stackTraceLimit = 100;
    
    // 或者使用 try-catch 包裹可疑代码
    try {
        // 你的代码
    } catch (e) {
        console.log('错误堆栈:', e.stack);
    }
    
  2. 逐步补环境

    • 先补 window 对象
    • 再补 document
    • 最后补具体的 API
  3. 使用现有的补环境框架

    • JSDOM:模拟完整的浏览器环境
    • Puppeteer:使用真实浏览器环境
    • vm2:安全的沙箱环境

JS补环境报错TypeError: Cannot read properties of undefined (reading ‘webdriver’)

这个错误是因为JavaScript代码检测 navigator.webdriver 属性时,该属性不存在。这是常见的反爬虫检测手段,很多网站通过这个属性来检测是否使用了自动化工具(如Selenium、Puppeteer)。

解决方案

1.最简方案 - 直接设置为 undefined 或 false

// 方案1:设置为 false(最常用)
Object.defineProperty(navigator, 'webdriver', {
    get: () => false,
    configurable: true
});

// 方案2:设置为 undefined(有些网站需要这样)
Object.defineProperty(navigator, 'webdriver', {
    get: () => undefined,
    configurable: true
});

// 方案3:直接删除属性
delete navigator.webdriver;

2.完整的环境伪装方案

// 完整的 navigator 对象伪装
const originalNavigator = Object.getOwnPropertyDescriptor(window, 'navigator');
if (originalNavigator && originalNavigator.configurable) {
    Object.defineProperty(window, 'navigator', {
        value: new Proxy(navigator, {
            get: function(target, property) {
                // 拦截 webdriver 属性
                if (property === 'webdriver') {
                    return false; // 或 undefined
                }
                
                // 拦截其他可能被检测的属性
                if (property === 'languages') {
                    return ['zh-CN', 'zh', 'en'];
                }
                
                if (property === 'plugins') {
                    return {
                        length: 5,
                        [Symbol.iterator]: function*() {
                            yield { name: 'Chrome PDF Plugin' };
                            yield { name: 'Chrome PDF Viewer' };
                            yield { name: 'Native Client' };
                        }
                    };
                }
                
                // 返回原始属性
                return target[property];
            }
        }),
        configurable: true,
        writable: true
    });
}

3.针对不同场景的解决方案

场景1:普通网站

// 大部分网站只需要设置 webdriver 为 false
Object.defineProperty(navigator, 'webdriver', {
    get: () => false
});

// 同时需要处理一些其他常见检测点
Object.defineProperty(navigator, 'plugins', {
    get: () => [1, 2, 3, 4, 5]
});

Object.defineProperty(navigator, 'languages', {
    get: () => ['zh-CN', 'zh', 'en', 'en-US']
});

场景2:高级反爬网站(如某宝、某东)

// 更复杂的伪装方案
const fakeNavigator = {};

// 复制原始 navigator 的所有属性
for (const key in navigator) {
    if (navigator.hasOwnProperty(key)) {
        fakeNavigator[key] = navigator[key];
    }
}

// 重写关键属性
fakeNavigator.webdriver = false;
fakeNavigator.plugins = [
    { name: 'Chrome PDF Plugin' },
    { name: 'Chrome PDF Viewer' },
    { name: 'Native Client' }
];
fakeNavigator.languages = ['zh-CN', 'zh', 'en'];

// 冻结对象,防止被修改检测
Object.defineProperty(window, 'navigator', {
    value: Object.freeze(fakeNavigator),
    configurable: false,
    writable: false
});

4.使用 Proxy 拦截所有访问

// 创建代理 navigator
const navigatorProxy = new Proxy(navigator, {
    get(target, property) {
        // 处理 webdriver
        if (property === 'webdriver') {
            return false;
        }
        
        // 处理其他可能被检测的属性
        const detectionProperties = [
            'webdriver',
            'plugins',
            'languages',
            'userAgent',
            'platform',
            'vendor',
            'maxTouchPoints',
            'hardwareConcurrency',
            'deviceMemory'
        ];
        
        if (detectionProperties.includes(property)) {
            console.log(`[补环境] navigator.${property} 被访问`);
        }
        
        // 返回原始值
        const value = target[property];
        return typeof value === 'function' ? value.bind(target) : value;
    }
});

// 替换 navigator
Object.defineProperty(window, 'navigator', {
    value: navigatorProxy,
    configurable: true
});

5.完整的反检测套件

class AntiDetection {
    constructor() {
        this.init();
    }
    
    init() {
        this.patchNavigator();
        this.patchWindow();
        this.patchDocument();
    }
    
    patchNavigator() {
        // webdriver 伪装
        Object.defineProperty(navigator, 'webdriver', {
            get: () => false
        });
        
        // Chrome 特征伪装
        if (navigator.userAgent.includes('Chrome')) {
            Object.defineProperties(navigator, {
                plugins: {
                    get: () => {
                        return {
                            length: 3,
                            0: { name: 'Chrome PDF Plugin' },
                            1: { name: 'Chrome PDF Viewer' },
                            2: { name: 'Native Client' }
                        };
                    }
                },
                languages: {
                    get: () => ['zh-CN', 'zh', 'en']
                },
                hardwareConcurrency: {
                    get: () => 8  // 常见的CPU核心数
                },
                deviceMemory: {
                    get: () => 8  // 8GB内存
                }
            });
        }
    }
    
    patchWindow() {
        // 处理 window 上的检测
        if (window.chrome) {
            // 伪装 chrome 对象
            window.chrome = {
                runtime: {},
                loadTimes: function() {},
                csi: function() {},
                app: {}
            };
        }
    }
    
    patchDocument() {
        // 处理 document 上的检测
        Object.defineProperty(document, 'hidden', { value: false });
        Object.defineProperty(document, 'visibilityState', { value: 'visible' });
    }
}

// 使用
new AntiDetection();

6.动态调试和检测

// 启用调试模式
const DEBUG = true;

// 监控所有 navigator 属性访问
const originalGet = Object.getOwnPropertyDescriptor;
Object.getOwnPropertyDescriptor = function(obj, prop) {
    if (obj === navigator && DEBUG) {
        console.log(`[检测] navigator.${prop} 被检测`);
    }
    return originalGet.call(this, obj, prop);
};

// 或者使用更加侵入式的方法
Object.defineProperty(navigator, 'webdriver', {
    configurable: true,
    get: function() {
        if (DEBUG) {
            console.trace('[检测] navigator.webdriver 被访问');
        }
        return false;
    }
});

7.针对特定框架的解决方案

Puppeteer 用户:

// 在启动 puppeteer 时添加参数
const browser = await puppeteer.launch({
    args: [
        '--disable-blink-features=AutomationControlled'
    ]
});

// 然后在页面中执行
await page.evaluateOnNewDocument(() => {
    Object.defineProperty(navigator, 'webdriver', {
        get: () => false
    });
});

Selenium 用户:

// ChromeOptions 设置
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-blink-features=AutomationControlled");

// 或者使用 CDP
Map<String, Object> params = new HashMap<>();
params.put("source", "Object.defineProperty(navigator, 'webdriver', { get: () => false })");
driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument", params);

8.检查是否还有其他检测点

// 运行这个脚本来检查常见的检测点
const detectionTests = [
    'navigator.webdriver',
    'window.chrome',
    'navigator.plugins.length',
    'navigator.languages',
    'document.__driver_evaluate',
    'document.__webdriver_evaluate',
    'document.$cdc_asdjflasutopfhvcZLmcfl_',
    'window.callPhantom',
    'window._phantom',
    'window.phantom'
];

detectionTests.forEach(test => {
    try {
        const result = eval(test);
        console.log(`${test}:`, result);
    } catch (e) {
        console.log(`${test}: Error - ${e.message}`);
    }
});

注意事项

  1. 执行时机很重要:必须在网站脚本执行之前就设置好这些属性
  2. 兼容性:不同浏览器可能需要不同的伪装策略
  3. 不要过度伪装:过于完美的伪装反而会被检测
  4. 动态更新:有些网站会多次检测,需要确保属性始终正确

总结 

到此这篇关于JavaScript补环境报错navigator is not defined几种解决方案的文章就介绍到这了,更多相关js补环境报错navigator is not defined内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用JS将字符串保存成文件到本地(.txt、.json、.md)

    使用JS将字符串保存成文件到本地(.txt、.json、.md)

    工作中有时需要通过JavaScript保存文件到本地,下面这篇文章主要给大家介绍了关于使用JS将字符串保存成文件到本地的相关资料,分别包括生成.txt、.json、.md等文件,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • js实现跨域访问的三种方法

    js实现跨域访问的三种方法

    这篇文章主要介绍了js实现跨域访问的三种方法,包括基于iframe实现跨域、基于script标签实现跨域以及后台代理方式 ,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • 使用Bootstrap做一个朝代历史表

    使用Bootstrap做一个朝代历史表

    Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的。这篇文章主要介绍了使用Bootstrap做一个朝代历史表,需要的朋友可以参考下
    2019-12-12
  • 微信小程序整个页面的自动适应布局的实现

    微信小程序整个页面的自动适应布局的实现

    这篇文章主要介绍了微信小程序整个页面的自动适应布局的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • JavaScript如何防止页面退格键回退

    JavaScript如何防止页面退格键回退

    本文主要介绍了JavaScript如何防止页面退格键回退,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • js实现GIF图片的分解和合成

    js实现GIF图片的分解和合成

    这篇文章主要为大家详细介绍了js实现GIF图片的分解和合成,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 使用JavaScript进行进制转换将字符串转换为十进制

    使用JavaScript进行进制转换将字符串转换为十进制

    JS 是一个很神奇的语言,可以将任意进制字符串转换为十进制,如二进制,八进制,十六进制, 第二数数不写即为最常用的转换为整型十进制
    2014-09-09
  • uniapp封装小程序雷达图组件的完整代码

    uniapp封装小程序雷达图组件的完整代码

    组件是一个单独且可复用的功能模块的封装,每个组件,包括如下几个部分:以组件名称为标记的开始标签和结束标签、组件内容、组件属性、组件属性值,这篇文章主要给大家介绍了关于uniapp封装小程序雷达图组件的相关资料,需要的朋友可以参考下
    2021-07-07
  • js前端获取用户位置及ip属地信息

    js前端获取用户位置及ip属地信息

    这篇文章主要为大家介绍了js前端获取用户位置及ip属地信息示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • js查看一个函数的执行时间实例代码

    js查看一个函数的执行时间实例代码

    本篇文章给大家分享一段实例代码,主要介绍js查看一个函数的执行时间,代码简单易懂,感兴趣的朋友一起跟着小编来学习学习吧
    2015-09-09

最新评论