{"id":17288327,"url":"https://github.com/theajack/disable-devtool","last_synced_at":"2025-05-13T17:05:19.002Z","repository":{"id":40502621,"uuid":"305972561","full_name":"theajack/disable-devtool","owner":"theajack","description":"Disable web developer tools from the f12 button, right-click and browser menu","archived":false,"fork":false,"pushed_at":"2024-12-31T03:00:13.000Z","size":730,"stargazers_count":2483,"open_issues_count":56,"forks_count":220,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-04-24T01:52:29.124Z","etag":null,"topics":["disable-devtool"],"latest_commit_sha":null,"homepage":"https://theajack.github.io/disable-devtool/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theajack.png","metadata":{"files":{"readme":"README.cn.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":"disable-devtool","ko_fi":"theajack","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2020-10-21T09:24:29.000Z","updated_at":"2025-04-23T06:11:47.000Z","dependencies_parsed_at":"2024-06-19T01:39:01.227Z","dependency_job_id":"72378bb9-d365-4e23-b06d-9cc99fac23c6","html_url":"https://github.com/theajack/disable-devtool","commit_stats":{"total_commits":103,"total_committers":5,"mean_commits":20.6,"dds":0.3398058252427184,"last_synced_commit":"4c8a2a0cb60dad4f2a8f1f13b0ecee940c30ac55"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theajack%2Fdisable-devtool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theajack%2Fdisable-devtool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theajack%2Fdisable-devtool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theajack%2Fdisable-devtool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theajack","download_url":"https://codeload.github.com/theajack/disable-devtool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253990460,"owners_count":21995774,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["disable-devtool"],"created_at":"2024-10-15T10:27:14.655Z","updated_at":"2025-05-13T17:05:18.982Z","avatar_url":"https://github.com/theajack.png","language":"TypeScript","readme":"\n\u003cp align=\"center\"\u003e\n    \u003ca href='https://www.github.com/theajack/disable-devtool'\u003e\n        \u003cimg src='https://shiyix.cn/images/disable-devtool3.png' width='240px'/\u003e\n    \u003c/a\u003e\n\u003c/p\u003e \n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.github.com/theajack/disable-devtool/stargazers\" target=\"_black\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/stars/theajack/disable-devtool?logo=github\" alt=\"stars\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.github.com/theajack/disable-devtool/network/members\" target=\"_black\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/forks/theajack/disable-devtool?logo=github\" alt=\"forks\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/disable-devtool\" target=\"_black\"\u003e\n        \u003cimg src=\"https://img.shields.io/npm/v/disable-devtool?logo=npm\" alt=\"version\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/disable-devtool\" target=\"_black\"\u003e\n        \u003cimg src=\"https://img.shields.io/npm/dm/disable-devtool?color=%23ffca28\u0026logo=npm\" alt=\"downloads\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.jsdelivr.com/package/npm/disable-devtool\" target=\"_black\"\u003e\n        \u003cimg src=\"https://data.jsdelivr.com/v1/package/npm/disable-devtool/badge\" alt=\"jsdelivr\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/theajack/disable-devtool/issues\"\u003e\u003cimg src=\"https://img.shields.io/github/issues-closed/theajack/disable-devtool.svg\" alt=\"issue\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/theajack\" target=\"_black\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Author-%20theajack%20-7289da.svg?logo=github\" alt=\"author\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.github.com/theajack/disable-devtool/blob/master/LICENSE\" target=\"_black\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/license/theajack/disable-devtool?color=%232DCE89\" alt=\"license\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://cdn.jsdelivr.net/npm/disable-devtool\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/minzip/disable-devtool.svg\" alt=\"Size\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/theajack/disable-devtool/search?l=javascript\"\u003e\u003cimg src=\"https://img.shields.io/github/languages/top/theajack/disable-devtool.svg\" alt=\"TopLang\"\u003e\u003c/a\u003e\n    \u003c!-- \u003ca href=\"https://www.github.com/theajack/disable-devtool\"\u003e\u003cimg src=\"https://img.shields.io/librariesio/dependent-repos/npm/disable-devtool.svg\" alt=\"Dependent\"\u003e\u003c/a\u003e --\u003e\n    \u003cimg src=\"https://img.shields.io/badge/test-passed-44BB44\" alt=\"test\"\u003e\n    \u003cimg src=\"https://shiyix.cn/api2/util/badge/stat?c=Visitors-disabledevtool\" alt=\"visitors\"\u003e\n\n\u003c/p\u003e\n\n\u003ch2\u003e🚀 一行代码搞定禁用web开发者工具 \u003c/h2\u003e\n\n**[English](https://github.com/theajack/disable-devtool/blob/master/README.md) | [在线试用](https://theajack.github.io/disable-devtool) | [更新日志](https://github.com/theajack/disable-devtool/blob/scripts/helper/version.md) | [Gitee](https://gitee.com/theajack/disable-devtool) | [留言板](https://theajack.github.io/message-board?app=disable-devtool) ｜ QQ交流群: 720626970**\n\n----\n\n开源维护不易，如果您有经济条件的话，可以捐赠给作者一杯咖啡\n\n\u003cp align=\"\"\u003e\n    \u003ca href=\"https://ko-fi.com/theajack\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Donate-Ko Fi-ff5f5f\" alt=\"test\"\u003e\n    \u003c/a\u003e    \n    \u003ca href=\"https://paypal.me/tackchen\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Donate-PayPal-142c8e\" alt=\"test\"\u003e\n    \u003c/a\u003e    \n    \u003ca href=\"https://shiyix.cn/images/wx-pay.png\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Donate-Wechat Pay-00c250\" alt=\"test\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n----\n\n## 0. 赞助商\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://alinsjs.github.io/docs\"\u003e\n        \u003cimg width=\"130\" src=\"https://shiyix.cn/images/alins.png\" alt=\"alins\"\u003e\n    \u003c/a\u003e    \n    \u003cp align=\"center\"\u003e\u003ca href=\"https://github.com/alinsjs/alins\"\u003eAlins - 极致优雅的UI框架\u003c/a\u003e\u003c/p\u003e\n\u003c/p\u003e\n\n## 1. 快速使用\n\n### 1.1 npm 引用\n\n```\nnpm i disable-devtool\n```\n\n```js\nimport DisableDevtool from 'disable-devtool';\n\nDisableDevtool();\n```\n\n### 1.2 script属性配置\n\n```html\n\u003cscript disable-devtool-auto src='https://cdn.jsdelivr.net/npm/disable-devtool'\u003e\u003c/script\u003e\n```\n\n或者通过版本引用:\n\n```html\n\u003c!--使用指定版本--\u003e\n\u003cscript disable-devtool-auto src='https://cdn.jsdelivr.net/npm/disable-devtool@x.x.x'\u003e\u003c/script\u003e\n\u003c!--使用最新版本--\u003e\n\u003cscript disable-devtool-auto src='https://cdn.jsdelivr.net/npm/disable-devtool@latest'\u003e\u003c/script\u003e\n```\n\n### 1.3 误触发问题定位帮助\n\n----\n\n\u003cdetails\u003e\n    \u003csummary\u003e如果您在使用过程中遇到问题，请点开我\u003c/summary\u003e\n\n因为设备、浏览器、运行环境众多，难免会有一些该库无法兼容的场景，此部分用于开发者自查问题，然后细节反馈到 issues，以帮助我们定位和解决bug\n\n#### 1.3.1 探测器被错误地触发\n\n对于部分情况下，如果没有打开控制台但是页面没关闭了或是跳转走了的问题，原因是某个探测器被错误地触发了，请使用以下代码定位是哪个探测器被误触发了：\n\n```js\nDisableDevtool({\n    ondevtoolopen: (type) =\u003e {\n        const info = 'devtool opened!; type =' + type;\n        alert(info);\n        // 如果担心阻塞页面 请使用 console.warn(info); 并打开控制台查看\n    },\n})\n```\n\n上述代码在使用脚本引用时需要这样使用\n\n```html\n\u003cscript src='https://cdn.jsdelivr.net/npm/disable-devtool'\u003e\u003c/script\u003e\n\u003cscript\u003e\n    DisableDevtool({\n        ondevtoolopen: (type) =\u003e {\n            const info = 'devtool opened!; type =' + type;\n            alert(info); // 如果担心阻塞页面 请使用 console.warn(info); 并打开控制台查看\n        },\n    })\n\u003c/script\u003e\n```\n\n#### 1.3.2 探测器没有被触发\n\n当通过任意方式打开了devtool，但是页面没有正确的关闭或者跳转时，首先请尝试打印以下内容，看看探测器是否在正常工作\n\n```js\nconsole.log(DisableDevtool.isRunning);\n```\n\n如果返回的是true，那么这就是一个不兼容的问题，原因是所有探测器都没有被触发，这种情况是比较棘手的，目前来看没有通用的定位方法\n\n请提交一个issue，尽可能详细地提供您使用的浏览器版本、设备型号及版本、运行环境，最好是有截图或者演示地址，我们后续会进行相应的问题排查\n\n\u003c/details\u003e\n\n----\n\n## 2.功能\n\ndisable-devtool 可以禁用所有一切可以进入开发者工具的方法，防止通过开发者工具进行的 ‘代码搬运’\n\n该库有以下特性:\n\n1. 支持可配置是否禁用右键菜单\n2. 禁用 f12 和 ctrl+shift+i 等快捷键\n3. 支持识别从浏览器菜单栏打开开发者工具并关闭当前页面\n4. 开发者可以绕过禁用 (url参数使用tk配合md5加密)\n5. 多种监测模式，支持几乎所有浏览器（IE,360,qq浏览器,FireFox,Chrome,Edge...）\n6. 高度可配置、使用极简、体积小巧\n7. 支持npm引用和script标签引用(属性配置)\n8. 识别真移动端与浏览器开发者工具设置插件伪造的移动端，为移动端节省性能\n9.  支持识别开发者工具关闭事件\n10. 支持可配置是否禁用选择、复制、剪切、粘贴功能\n11. 支持识别 eruda 和 vconsole 调试工具\n12. 支持挂起和恢复探测器工作\n13. 支持配置ignore属性，用以自定义控制是否启用探测器\n14. 支持配置iframe中所有父页面的开发者工具禁用\n\n## 3. 使用\n\n### 3.1 npm使用时的配置参数\n\n推荐使用这种方式安装使用，使用script脚本可以被代理单独拦截掉从而无法执行\n\n安装 disable-devtool\n\n```\nnpm i disable-devtool\n```\n\n```js\nimport DisableDevtool from 'disable-devtool';\n\nDisableDevtool(options);\n```\n\n#### 3.1.1 返回值\n\n返回值 DisableDevtool 的返回值为如下类型\n\n```ts\ninterface IDDResult {\n    success: boolean; // 表示是否正常启用\n    reason: string; // 未正常启用的原因\n}\n```\n\n#### 3.1.2 参数\n\noptions中的参数与说明如下：\n\n```ts\ninterface IConfig {\n    md5?: string; // 绕过禁用的md5值，详情见3.2，默认不启用绕过禁用\n    url?: string; // 关闭页面失败时的跳转页面，默认值为localhost\n    tkName?: string; // 绕过禁用时的url参数名称，默认为 ddtk\n    ondevtoolopen?(type: DetectorType, next: Function): void; // 开发者面板打开的回调，启用时url参数无效，type 为监测模式，详见3.5， next函数是关闭当前窗口\n    ondevtoolclose?(): void; // 开发者面板关闭的回调\n    interval?: number; // 定时器的时间间隔 默认200ms\n    disableMenu?: boolean; // 是否禁用右键菜单 默认为true\n    stopIntervalTime?: number; // 在移动端时取消监视的等待时长\n    clearIntervalWhenDevOpenTrigger?: boolean; // 是否在触发之后停止监控 默认为false， 在使用ondevtoolclose时该参数无效\n    detectors?: Array\u003cDetectorType\u003e; // 启用的检测器 检测器详情见 3.5 默认为全部，建议使用全部\n    clearLog?: boolean; // 是否每次都清除log\n    disableSelect?: boolean; // 是否禁用选择文本 默认为false\n    disableCopy?: boolean; // 是否禁用复制 默认为false\n    disableCut?: boolean; // 是否禁用剪切 默认为false\n    disablePaste: boolean; // 是否禁用粘贴 默认为false\n    ignore?: (string|RegExp)[] | null | (()=\u003eboolean); // 某些情况忽略禁用\n    disableIframeParents?: boolean; // iframe中是否禁用所有父窗口\n    timeOutUrl?: string; // 关闭页面超时跳转的url，默认为https://theajack.github.io/disable-devtool/404.html?h=${encodeURIComponent(location.host)}\n    rewriteHTML: string; // 检测到打开之后重写页面\n}\n\nenum DetectorType {\n  Unknown = -1,\n  RegToString = 0, // 根据正则检测\n  DefineId, // 根据dom id检测\n  Size, // 根据窗口尺寸检测\n  DateToString, // 根据Date.toString 检测\n  FuncToString, // 根据Function.toString 检测\n  Debugger, // 根据断点检测，仅在ios chrome 真机情况下有效\n  Performance, // 根据log大数据性能检测\n  DebugLib, // 检测第三方调试工具 eruda 和 vconsole   \n};\n```\n\n### 3.2 md5 与 tk 绕过禁用\n\n该库中使用 key 与 md5 配合的方式使得开发者可以在线上绕过禁用。\n\n流程如下：\n\n先指定一个 key a（该值不要记录在代码中），使用 md5 加密得到一个值 b，将b作为 md5 参数传入，开发者在访问 url 的时候只需要带上url参数 ddtk=a，便可以绕过禁用。\n\ndisableDevtool对象暴露了 md5 方法，可供开发者加密时使用：\n\n```js\nDisableDevtool.md5('xxx');\n```\n\n### 3.3 script使用属性配置\n\n```html\n\u003cscript \n    disable-devtool-auto\n    src='https://cdn.jsdelivr.net/npm/disable-devtool'\n    md5='xxx'\n    url='xxx'\n    tk-name='xxx'\n    interval='xxx'\n    disable-menu='xxx'\n    detectors='xxx'\n    clear-log='true'\n    disable-select='true'\n    disable-copy='true'\n    disable-cut='true'\n    disable-paste='true'\n\u003e\u003c/script\u003e\n```\n\n注：\n\n1. 如希望自动禁用，属性配置时必须要带上 `disable-devtool-auto` 属性\n2. 属性配置都是可选的，字段与3.1中一致，区别是将驼峰形式改成横线分割\n3. 该script标签建议放在body最底部\n4. detectors 需要使用空格分割，如 detectors='1 2 3'\n\n### 3.4 script不使用属性配置\n\n```html\n\u003cscript src='https://cdn.jsdelivr.net/npm/disable-devtool'\u003e\u003c/script\u003e\n\u003cscript\u003e\n    DisableDevtool({\n        // 参数与3.1中一致\n    })\n\u003c/script\u003e\n```\n\n### 3.5 监测模式\n\nDisable-Devtool 有以下几种监测模式, DisableDevtool.DetectorType 为所有的监测模式枚举\n\n```ts\nenum DetectorType {\n  Unknown = -1,\n  RegToString = 0, // 根据正则检测\n  DefineId, // 根据dom id检测\n  Size, // 根据窗口尺寸检测 // 0.3.5版本后该探测器默认不启用\n  DateToString, // 根据Date.toString 检测\n  FuncToString, // 根据Function.toString 检测\n  Debugger, // 根据断点检测，仅在ios chrome 真机情况下有效\n  Performance, // 根据log大数据性能检测\n  DebugLib, // 检测第三方调试工具\n};\n```\n\nondevtoolopen 事件的回调参数就是被触发的监测模式\n\n可以在 ondevtoolopen 里执行业务逻辑，比如做数据上报、用户行为分析等\n\n```ts\nDisableDevtool({\n    ondevtoolopen(type, next){\n        alert('Devtool opened with type:' + type);\n        next();\n    }\n});\n```\n\n### 3.6 其他 API\n\n#### 3.6.1 isRunning\n\n用于获取 DisableDevtool 是否正在运行中 (挂起或忽略状态也视为运行中，因为可以动态开启)\n\n```js\nDisableDevtool.isRunning;\n```\n\n#### 3.6.2 isSuspend\n\n用于获取或设置 DisableDevtool 是否被挂起 (挂起状态所有的禁用都将暂时失效)\n\n```js\nDisableDevtool.isSuspend = true;\nDisableDevtool.isSuspend = false;\n```\n\n#### 3.6.3 config.ignore\n\nignore 用于自定义某些忽略的场景\n\n1. 传入数组\n\n传入数组是支持 字符串和正则表达式，表示匹配链接中是否含有传入的内容，使用如下\n\n```js\nDisableDevtool({\n    ignore: [\n        '/user/login', // 当链接中含有该内容时禁用暂时被忽略\n        /\\/user\\/[0-9]{6}/, // 当链接匹配该正则时禁用暂时被忽略\n    ]\n});\n```\n\n2. 传入函数\n\n传入函数表示自定义判断条件，返回一个bool类型，使用如下\n\n```js\nDisableDevtool({\n    ignore: () =\u003e {\n        return userType === 'admin'; // 当是管理员时忽略禁用\n    }\n});\n```\n\n#### 3.6.4 version\n\n用于获取 DisableDevtool 版本号\n\n```js\nDisableDevtool.version;\n```","funding_links":["https://opencollective.com/disable-devtool","https://ko-fi.com/theajack","https://paypal.me/tackchen"],"categories":["TypeScript","Packages"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheajack%2Fdisable-devtool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheajack%2Fdisable-devtool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheajack%2Fdisable-devtool/lists"}