Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美成人小视频,日韩精品综合,欧美精品免费在线

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          「webpack」webpack 中最易混淆的 5

          「webpack」webpack 中最易混淆的 5 個(gè)知識(shí)點(diǎn)

          .webpack 中,module,chunk 和 bundle 的區(qū)別是什么?

          說(shuō)實(shí)話我剛開始看 webpack 文檔的時(shí)候,對(duì)這 3 個(gè)名詞云里霧里的,感覺他們都在說(shuō)打包文件,但是一會(huì)兒 chunk 一會(huì)兒 bundle 的,逐漸就迷失在細(xì)節(jié)里了,所以我們要跳出來(lái),從宏觀的角度來(lái)看這幾個(gè)名詞。

          webpack 官網(wǎng)對(duì) chunk 和 bundle 做出了解釋[3],說(shuō)實(shí)話太抽象了,我這里舉個(gè)例子,給大家形象化地解釋一下。

          首先我們?cè)?src 目錄下寫我們的業(yè)務(wù)代碼,引入 index.js、utils.js、common.js 和 index.css 這 4 個(gè)文件,目錄結(jié)構(gòu)如下:

          src/
          ├── index.css
          ├── index.html # 這個(gè)是 HTML 模板代碼
          ├── index.js
          ├── common.js
          └── utils.js
          

          index.css 寫一點(diǎn)兒簡(jiǎn)單的樣式:

          body {
              background-color: red;
          }
          

          utils.js 文件寫個(gè)求平方的工具函數(shù):

          export function square(x) {
              return x * x;
          }
          

          common.js 文件寫個(gè) log 工具函數(shù):

          module.exports = {
            log: (msg) => {
              console.log('hello ', msg)
            }
          }
          

          index.js 文件做一些簡(jiǎn)單的修改,引入 css 文件和 common.js:

          import './index.css';
          const { log } = require('./common');
          
          log('webpack');
          

          webpack 的配置如下:

          {
              entry: {
                  index: "../src/index.js",
                  utils: '../src/utils.js',
              },
              output: {
                  filename: "[name].bundle.js", // 輸出 index.js 和 utils.js
              },
              module: {
                  rules: [
                      {
                          test: /\.css$/,
                          use: [
                              MiniCssExtractPlugin.loader, // 創(chuàng)建一個(gè) link 標(biāo)簽
                              'css-loader', // css-loader 負(fù)責(zé)解析 CSS 代碼, 處理 CSS 中的依賴
                          ],
                      },
                  ]
              }
              plugins: [
                  // 用 MiniCssExtractPlugin 抽離出 css 文件,以 link 標(biāo)簽的形式引入樣式文件
                  new MiniCssExtractPlugin({
                      filename: 'index.bundle.css' // 輸出的 css 文件名為 index.css
                  }),
              ]
          }
          

          我們運(yùn)行一下 webpack,看一下打包的結(jié)果:

          我們可以看出,index.css 和 common.js 在 index.js 中被引入,打包生成的 index.bundle.css 和 index.bundle.js 都屬于 chunk 0,utils.js 因?yàn)槭仟?dú)立打包的,它生成的 utils.bundle.js 屬于 chunk 1。

          感覺還有些繞?我做了一張圖,你肯定一看就懂:

          看這個(gè)圖就很明白了:

          1. 對(duì)于一份同邏輯的代碼,當(dāng)我們手寫下一個(gè)一個(gè)的文件,它們無(wú)論是 ESM 還是 commonJS 或是 AMD,他們都是 module
          2. 當(dāng)我們寫的 module 源文件傳到 webpack 進(jìn)行打包時(shí),webpack 會(huì)根據(jù)文件引用關(guān)系生成 chunk 文件,webpack 會(huì)對(duì)這個(gè) chunk 文件進(jìn)行一些操作;
          3. webpack 處理好 chunk 文件后,最后會(huì)輸出 bundle 文件,這個(gè) bundle 文件包含了經(jīng)過(guò)加載和編譯的最終源文件,所以它可以直接在瀏覽器中運(yùn)行。

          一般來(lái)說(shuō)一個(gè) chunk 對(duì)應(yīng)一個(gè) bundle,比如上圖中的 utils.js -> chunks 1 -> utils.bundle.js;但也有例外,比如說(shuō)上圖中,我就用 MiniCssExtractPlugin 從 chunks 0 中抽離出了 index.bundle.css 文件。

          一句話總結(jié):

          modulechunkbundle 其實(shí)就是同一份邏輯代碼在不同轉(zhuǎn)換場(chǎng)景下的取了三個(gè)名字:

          我們直接寫出來(lái)的是 module,webpack 處理時(shí)是 chunk,最后生成瀏覽器可以直接運(yùn)行的 bundle。


          2.filename 和 chunkFilename 的區(qū)別

          filename

          filename 是一個(gè)很常見的配置,就是對(duì)應(yīng)于 entry 里面的輸入文件,經(jīng)過(guò)webpack 打包后輸出文件的文件名。比如說(shuō)經(jīng)過(guò)下面的配置,生成出來(lái)的文件名為 index.min.js

          {
              entry: {
                  index: "../src/index.js"
              },
              output: {
                  filename: "[name].min.js", // index.min.js
              }
          }
          

          chunkFilename

          chunkFilename 指未被列在 entry 中,卻又需要被打包出來(lái)的 chunk 文件的名稱。一般來(lái)說(shuō),這個(gè) chunk 文件指的就是要懶加載的代碼。

          比如說(shuō)我們業(yè)務(wù)代碼中寫了一份懶加載 lodash 的代碼:

          // 文件:index.js
          
          // 創(chuàng)建一個(gè) button
          let btn = document.createElement("button");
          btn.innerHTML = "click me";
          document.body.appendChild(btn);
          
          // 異步加載代碼
          async function getAsyncComponent() {
              var element = document.createElement('div');
              const { default: _ } = await import('lodash');
          
              element.innerHTML = _.join(['Hello!', 'dynamic', 'imports', 'async'], ' ');
          
              return element;
          }
          
          // 點(diǎn)擊 button 時(shí),懶加載 lodash,在網(wǎng)頁(yè)上顯示 Hello! dynamic imports async
          btn.addEventListener('click', () => {
              getAsyncComponent().then(component => {
                  document.body.appendChild(component);
              })
          })
          

          我們的 webpack 不做任何配置,還是原來(lái)的配置代碼:

          {
              entry: {
                  index: "../src/index.js"
              },
              output: {
                  filename: "[name].min.js", // index.min.js
              }
          }
          

          這時(shí)候的打包結(jié)果如下:

          這個(gè) 1.min.js 就是異步加載的 chunk 文件。文檔[4]里這么解釋:

          output.chunkFilename 默認(rèn)使用 [id].js 或從 output.filename 中推斷出的值([name] 會(huì)被預(yù)先替換為 [id][id].

          文檔寫得太抽象,我們不如結(jié)合上面的例子來(lái)看:

          output.filename 的輸出文件名是 [name].min.js[name] 根據(jù) entry 的配置推斷為 index,所以輸出為 index.min.js

          由于 output.chunkFilename 沒(méi)有顯示指定,就會(huì)把 [name] 替換為 chunk 文件的 id號(hào),這里文件的 id 號(hào)是 1,所以文件名就是 1.min.js

          如果我們顯式配置 chunkFilename,就會(huì)按配置的名字生成文件:

          {
              entry: {
                  index: "../src/index.js"
              },
              output: {
                  filename: "[name].min.js",  // index.min.js
                  chunkFilename: 'bundle.js', // bundle.js
              }
          }
          

          一句話總結(jié):

          filename列在 entry 中,打包后輸出的文件的名稱。

          chunkFilename未列在 entry 中,卻又需要被打包出來(lái)的文件的名稱。


          3.webpackPrefetch、webpackPreload 和 webpackChunkName 到底是干什么的?

          這幾個(gè)名詞其實(shí)都是 webpack 魔法注釋(magic comments)[5]里的,文檔中說(shuō)了 6 個(gè)配置,配置都可以組合起來(lái)用。我們說(shuō)說(shuō)最常用的三個(gè)配置。

          webpackChunkName

          前面舉了個(gè)異步加載 lodash 的例子,我們最后把 output.chunkFilename 寫死成 bundle.js。在我們的業(yè)務(wù)代碼中,不可能只異步加載一個(gè)文件,所以寫死肯定是不行的,但是寫成 [name].bundle.js 時(shí),打包的文件又是意義不明、辨識(shí)度不高的 chunk id

          {
              entry: {
                  index: "../src/index.js"
              },
              output: {
                  filename: "[name].min.js",  // index.min.js
                  chunkFilename: '[name].bundle.js', // 1.bundle.js,chunk id 為 1,辨識(shí)度不高
              }
          }
          

          這時(shí)候 webpackChunkName 就可以派上用場(chǎng)了。我們可以在 import 文件時(shí),在 import里以注釋的形式為 chunk 文件取別名:

          async function getAsyncComponent() {
              var element = document.createElement('div');
            
              // 在 import 的括號(hào)里 加注釋 /* webpackChunkName: "lodash" */ ,為引入的文件取別名
              const { default: _ } = await import(/* webpackChunkName: "lodash" */ 'lodash');
          
              element.innerHTML = _.join(['Hello!', 'dynamic', 'imports', 'async'], ' ');
          
              return element;
          }
          

          這時(shí)候打包生成的文件是這樣的:

          現(xiàn)在問(wèn)題來(lái)了,lodash 是我們?nèi)〉拿郑吹览韥?lái)說(shuō)應(yīng)該生成 lodash.bundle.js 啊,前面的 vendors~ 是什么玩意?

          其實(shí) webpack 懶加載是用內(nèi)置的一個(gè)插件 SplitChunksPlugin[6] 實(shí)現(xiàn)的,這個(gè)插件里面有些默認(rèn)配置項(xiàng)[7],比如說(shuō) automaticNameDelimiter,默認(rèn)的分割符就是 ~,所以最后的文件名才會(huì)出現(xiàn)這個(gè)符號(hào),這塊兒內(nèi)容我就不引申了,感興趣的同學(xué)可以自己研究一下。

          webpackPrefetch 和 webpackPreload

          這兩個(gè)配置一個(gè)叫預(yù)拉取(Prefetch),一個(gè)叫預(yù)加載(Preload),兩者有些細(xì)微的不同,我們先說(shuō)說(shuō) webpackPreload

          在上面的懶加載代碼里,我們是點(diǎn)擊按鈕時(shí),才會(huì)觸發(fā)異步加載 lodash 的動(dòng)作,這時(shí)候會(huì)動(dòng)態(tài)的生成一個(gè) script 標(biāo)簽,加載到 head 頭里:

          如果我們 import 的時(shí)候添加 webpackPrefetch

          ...
          
          const { default: _ } = await import(/* webpackChunkName: "lodash" */ /* webpackPrefetch: true */ 'lodash');
          
          ...
          

          就會(huì)以 <link rel="prefetch" as="script"> 的形式預(yù)拉取 lodash 代碼:

          這個(gè)異步加載的代碼不需要手動(dòng)點(diǎn)擊 button 觸發(fā),webpack 會(huì)在父 chunk 完成加載后,閑時(shí)加載 lodash 文件。

          webpackPreload 是預(yù)加載當(dāng)前導(dǎo)航下可能需要資源,他和 webpackPrefetch 的主要區(qū)別是:

          • preload chunk 會(huì)在父 chunk 加載時(shí),以并行方式開始加載。prefetch chunk 會(huì)在父 chunk 加載結(jié)束后開始加載。
          • preload chunk 具有中等優(yōu)先級(jí),并立即下載。prefetch chunk 在瀏覽器閑置時(shí)下載。
          • preload chunk 會(huì)在父 chunk 中立即請(qǐng)求,用于當(dāng)下時(shí)刻。prefetch chunk 會(huì)用于未來(lái)的某個(gè)時(shí)刻

          一句話總結(jié):

          webpackChunkName 是為預(yù)加載的文件取別名,webpackPrefetch 會(huì)在瀏覽器閑置下載文件,webpackPreload 會(huì)在父 chunk 加載時(shí)并行下載文件。


          4.hash、chunkhash、contenthash 有什么不同?

          首先來(lái)個(gè)背景介紹,哈希一般是結(jié)合 CDN 緩存來(lái)使用的。如果文件內(nèi)容改變的話,那么對(duì)應(yīng)文件哈希值也會(huì)改變,對(duì)應(yīng)的 HTML 引用的 URL 地址也會(huì)改變,觸發(fā) CDN 服務(wù)器從源服務(wù)器上拉取對(duì)應(yīng)數(shù)據(jù),進(jìn)而更新本地緩存。

          hash

          hash 計(jì)算是跟整個(gè)項(xiàng)目的構(gòu)建相關(guān),我們做一個(gè)簡(jiǎn)單的 demo。

          沿用案例 1 的 demo 代碼,文件目錄如下:

          src/
          ├── index.css
          ├── index.html
          ├── index.js
          └── utils.js
          

          webpack 的核心配置如下(省略了一些 module 配置信息):

          {
              entry: {
                  index: "../src/index.js",
                  utils: '../src/utils.js',
              },
              output: {
                  filename: "[name].[hash].js",  // 改為 hash
              },
              
              ......
              
              plugins: [
                  new MiniCssExtractPlugin({
                      filename: 'index.[hash].css' // 改為 hash
                  }),
              ]
          }
          

          生成的文件名如下:

          我們可以發(fā)現(xiàn),生成文件的 hash 和項(xiàng)目的構(gòu)建 hash 都是一模一樣的。

          chunkhash

          因?yàn)?hash 是項(xiàng)目構(gòu)建的哈希值,項(xiàng)目中如果有些變動(dòng),hash 一定會(huì)變,比如說(shuō)我改動(dòng)了 utils.js 的代碼,index.js 里的代碼雖然沒(méi)有改變,但是大家都是用的同一份 hash。hash 一變,緩存一定失效了,這樣子是沒(méi)辦法實(shí)現(xiàn) CDN 和瀏覽器緩存的。

          chunkhash 就是解決這個(gè)問(wèn)題的,它根據(jù)不同的入口文件(Entry)進(jìn)行依賴文件解析、構(gòu)建對(duì)應(yīng)的 chunk,生成對(duì)應(yīng)的哈希值。

          我們?cè)倥e個(gè)例子,我們對(duì) utils.js 里文件進(jìn)行改動(dòng):

          export function square(x) {
              return x * x;
          }
          
          // 增加 cube() 求立方函數(shù)
          export function cube(x) {
              return x * x * x;
          }
          

          然后把 webpack 里的所有 hash 改為 chunkhash:

          {
              entry: {
                  index: "../src/index.js",
                  utils: '../src/utils.js',
              },
              output: {
                  filename: "[name].[chunkhash].js", // 改為 chunkhash
              },
                    
              ......
              
              plugins: [
                  new MiniCssExtractPlugin({
                      filename: 'index.[chunkhash].css' // // 改為 chunkhash
                  }),
              ]
          }
          

          構(gòu)建結(jié)果如下:

          我們可以看出,chunk 0 的 hash 都是一樣的,chunk 1 的 hash 和上面的不一樣。

          假設(shè)我又把 utils.js 里的 cube() 函數(shù)去掉,再打包:

          對(duì)比可以發(fā)現(xiàn),只有 chunk 1 的 hash 發(fā)生變化,chunk 0 的 hash 還是原來(lái)的。

          contenthash

          我們更近一步,index.js 和 index.css 同為一個(gè) chunk,如果 index.js 內(nèi)容發(fā)生變化,但是 index.css 沒(méi)有變化,打包后他們的 hash 都發(fā)生變化,這對(duì) css 文件來(lái)說(shuō)是一種浪費(fèi)。如何解決這個(gè)問(wèn)題呢?

          contenthash 將根據(jù)資源內(nèi)容創(chuàng)建出唯一 hash,也就是說(shuō)文件內(nèi)容不變,hash 就不變。

          我們修改一下 webpack 的配置:

          {
              entry: {
                  index: "../src/index.js",
                  utils: '../src/utils.js',
              },
              output: {
                  filename: "[name].[chunkhash].js",
              },
                
              ......
              
              plugins: [
                  new MiniCssExtractPlugin({
                      filename: 'index.[contenthash].css' // 這里改為 contenthash
                  }),
              ]
          }
          

          我們對(duì) index.js 文件做了 3 次修改(就是改了改 log 函數(shù)的輸出內(nèi)容,過(guò)于簡(jiǎn)單就先不寫了),然后分別構(gòu)建,結(jié)果截圖如下:

          我們可以發(fā)現(xiàn),css 文件的 hash 都沒(méi)有發(fā)生改變。

          一句話總結(jié):

          hash 計(jì)算與整個(gè)項(xiàng)目的構(gòu)建相關(guān);

          chunkhash 計(jì)算與同一 chunk 內(nèi)容相關(guān);

          contenthash 計(jì)算與文件內(nèi)容本身相關(guān)。


          5.sourse-map 中 eval、cheap、inline 和 module 各是什么意思?

          sourse-map ,里面都有個(gè) map 了,肯定是映射的意思。sourse-map 就是一份源碼和轉(zhuǎn)換后代碼的映射文件。具體的原理內(nèi)容較多,感興趣的同學(xué)可以自行搜索,我這里就不多言了。

          我們先從官網(wǎng)上看看 sourse-map 有多少種類型:

          emmmm,13 種,告辭。

          如果再仔細(xì)看一下,就發(fā)現(xiàn)這 13 種大部分都是 evalcheapinlinemodule這 4 個(gè)詞排列組合的,我做了個(gè)簡(jiǎn)單的表格,比官網(wǎng)上直白多了:

          參數(shù)參數(shù)解釋eval打包后的模塊都使用 eval() 執(zhí)行,行映射可能不準(zhǔn);不產(chǎn)生獨(dú)立的 map 文件cheapmap 映射只顯示行不顯示列,忽略源自 loader 的 source mapinline映射文件以 base64 格式編碼,加載 bundle 文件最后,不產(chǎn)生獨(dú)立的 map 文件module增加對(duì) loader source map 和第三方模塊的映射

          還不明白?可以看看 demo。

          我們對(duì) webpack 做一些配置,devtool 是專門配置 source-map 的。

          ......
          
          {
              devtool: 'source-map',
          }
          
          ......
          

          index.js 文件為了簡(jiǎn)便,我們只寫一行代碼,為了得出報(bào)錯(cuò)信息,我們故意拼錯(cuò):

          console.lg('hello source-map !') // log 寫成 lg
          

          下面我們?cè)囈辉嚦R姷膸讉€(gè)配置:

          source-map

          source-map 是最大而全的,會(huì)生成獨(dú)立 map 文件:

          注意下圖光標(biāo)的位置,source-map 會(huì)顯示報(bào)錯(cuò)的行列信息:

          cheap-sourse-map

          cheap,就是廉價(jià)的意思,它不會(huì)產(chǎn)生列映射,相應(yīng)的體積會(huì)小很多,我們和 sourse-map 的打包結(jié)果比一下,只有原來(lái)的 1/4 。

          eval-source-map

          eval-source-map 會(huì)以 eval() 函數(shù)打包運(yùn)行模塊,不產(chǎn)生獨(dú)立的 map 文件,會(huì)顯示報(bào)錯(cuò)的行列信息:

          // index.bundle.js 文件
          
          !function(e) {
              // ......
              // 省略不重要的代碼
              // ......
          }([function(module, exports) {
              eval("console.lg('hello source-map !');//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vc3JjL2luZGV4Mi5qcz9mNmJjIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsZyJdLCJtYXBwaW5ncyI6IkFBQUFBLE9BQU8sQ0FBQ0MsRUFBUixDQUFXLG9CQUFYIiwiZmlsZSI6IjAuanMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zb2xlLmxnKCdoZWxsbyBzb3VyY2UtbWFwICEnKSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0\n")
          }
          ]);
          

          inline-source-map

          映射文件以 base64 格式編碼,加在 bundle 文件最后,不產(chǎn)生獨(dú)立的 map 文件。加入 map 文件后,我們可以明顯地看到包體積變大了;

          // index.bundle.js 文件
          
          !function(e) {
          
          }([function(e, t) {
              console.lg("hello source-map !")
          }
          ]);
          //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4uL3NyYy9pbmRleDIuanMiXSwibmFtZXMiOlsiaW5zdGFsbGVkTW9kdWxlcyIsIl9fd2VicGFja19yZXF1aXJ......
          
          // base64 太長(zhǎng)了,我刪了一部分,領(lǐng)會(huì)精神
          

          常用配置:

          上面的幾個(gè)例子都是演示,結(jié)合[官網(wǎng)推薦](https://webpack.docschina.org/configuration/devtool/#%E5%AF%B9%E4%BA%8E%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83[8])和實(shí)際經(jīng)驗(yàn),常用的配置其實(shí)是這幾個(gè):

          1.source-map

          大而全,啥都有,就因?yàn)樯抖加锌赡軙?huì)讓 webpack 構(gòu)建時(shí)間變長(zhǎng),看情況使用。

          2.cheap-module-eval-source-map

          這個(gè)一般是開發(fā)環(huán)境(dev)推薦使用,在構(gòu)建速度報(bào)錯(cuò)提醒上做了比較好的均衡。

          3.cheap-module-source-map

          一般來(lái)說(shuō),生產(chǎn)環(huán)境是不配 source-map 的,如果想捕捉線上的代碼報(bào)錯(cuò),我們可以用這個(gè)

          般地,URL和URI比較難以區(qū)分。接下來(lái),本文以區(qū)分URL和URI為引子,詳細(xì)介紹URL的用法,JavaScript重文·也許你該知道瀏覽器輸入 URL 后發(fā)生了什么?

          與URI區(qū)別

          URI是Uniform Resource Identifier的縮寫,稱為統(tǒng)一資源標(biāo)識(shí)符。URI是一個(gè)通用的概念,由兩個(gè)主要的子集URL和URN構(gòu)成,URL是通過(guò)描述資源的位置來(lái)標(biāo)識(shí)資源的,而URN則是通過(guò)名字來(lái)識(shí)別資源的,與它們當(dāng)前所處位置無(wú)關(guān)

          URL是Uniform Resource Locator的縮寫,稱為統(tǒng)一資源定位符。URL正是使用web瀏覽器等訪問(wèn)web頁(yè)面時(shí)需要輸入的網(wǎng)頁(yè)地址

          URL是一種強(qiáng)有力的工具。但URL并不完美。它表示的是實(shí)際的地址,而不是準(zhǔn)確的名字。這種方案的缺點(diǎn)在于如果資源被移走了,URL也就不再有效了。那時(shí),它就無(wú)法對(duì)對(duì)象進(jìn)行定位了

          如果有了對(duì)象的準(zhǔn)確名稱,則不論其位于何處都可以找到這個(gè)對(duì)象。就像人一樣,只要給定了資源的名稱和其他一些情況,無(wú)論資源移到何處,都能夠追蹤到它。為了應(yīng)對(duì)這個(gè)問(wèn)題,因特網(wǎng)工程任務(wù)組(Internet Engineering Task Force, IETF) 已經(jīng)對(duì)URN的新標(biāo)準(zhǔn)做了一段時(shí)間的研究了。無(wú)論對(duì)象搬移到什么地方,URN都能為對(duì)象提供一個(gè)穩(wěn)定的名稱

          但是,從URL轉(zhuǎn)換成URN是一項(xiàng)巨大的工程,支持URN需要進(jìn)行很多改動(dòng)——標(biāo)準(zhǔn)主體的一致性,對(duì)各種HTTP應(yīng)用程序的修改等。所以,還要等待更合適的時(shí)機(jī)才能進(jìn)行這種轉(zhuǎn)換

          URL語(yǔ)法

          URL語(yǔ)法建立在由下面9部分構(gòu)成的通用格式上。其中,URL最重要的3個(gè)部分是方案(scheme)、主機(jī)(host)和路徑(path)

          <scheme>://<user>:<password>@<host>:<port>/<path>:<params>?<query>#<frag>
          

          【方案】

          方案實(shí)際上是規(guī)定如何訪問(wèn)指定資源的主要標(biāo)識(shí)符,它會(huì)告訴負(fù)責(zé)解析URL的應(yīng)用程序應(yīng)該使用什么協(xié)議

          方案組件必須以一個(gè)字母符號(hào)開始,由第一個(gè)“:”符號(hào)將其與URL的其余部分分隔開來(lái)。方案名是大小寫無(wú)關(guān)的,因此URL“http://www.hardware.com”和“HTTP://www.hardware.com” 是等價(jià)的

          常見的方案如下

          1、HTTP

          HTTP是一種超文本傳輸協(xié)議方案,除了沒(méi)有用戶名和密碼之外,與通用的URL格式相符。如果省略了端口,就默認(rèn)為80

          基本格式:

          http://<host>:<port>/<path>?<query>#<frag>
          

          示例:

          http://www.hardware.com/index.html
          http://www.hardware.com:80/index.html
          

          2、https

          方案https與方案http是一對(duì)。唯一的區(qū)別在于方案https使用了網(wǎng)景的SSL, SSL為HTTP連接提供了端到端的加密機(jī)制。其語(yǔ)法與HTTP的語(yǔ)法相同,默認(rèn)端口為443

          基本格式:

          https://<host>:<port>/<path>?<query>#<frag>
          

          示例:

          https://www.hardware.com/secure.html
          

          3、Mailto

          Mailto URL指向的是E-mail地址。由于E-mail的行為與其他方案都有所不同(它并不指向任何可以直接訪問(wèn)的對(duì)象),所以mailto URL的格式與標(biāo)準(zhǔn)URL的格式也有所不同

          示例:

          mailto:joe@hardware.com
          

          4、ftp

          文件傳輸協(xié)議URL可以用來(lái)從FTP服務(wù)器上下載或向其上傳文件,并獲取FTP服務(wù)器上的目錄結(jié)構(gòu)內(nèi)容的列表

          在Web和URL出現(xiàn)之前,F(xiàn)TP就已經(jīng)存在了。Web應(yīng)用程序?qū)TP作為一種數(shù)據(jù)訪問(wèn)方案使用

          基本格式:

          ftp://<user>:<password>@<host>:<port>/<path>;<params>
          

          示例:

          ftp://anonymous:joe%40hardware.com@prep.ai.mit.edu:21/pub/gnu/
          

          5、rtsp,rtspu

          RTSP URL是可以通過(guò)實(shí)時(shí)流傳輸協(xié)議(Real Time Streaming Protocol)解析的音/視頻媒體資源的標(biāo)識(shí)符

          方案rtspu中的u表示它是使用UDP協(xié)議來(lái)獲取資源的

          基本格式:

          rtsp://<user>:<password>@<host>:<port>/<path>
          rtspu://<user>:<password>@<host>:<port>/<path>
          

          示例:

          rtsp://www.hardware.com:554/interview/cto_video
          

          6、file

          方案file表示一臺(tái)指定主機(jī)(通過(guò)本地磁盤、網(wǎng)絡(luò)文件系統(tǒng)或其他一些文件共享系統(tǒng))上可直接訪問(wèn)的文件。各字段都遵循通用格式。如果省略了主機(jī)名,就默認(rèn)為正在使用URL的本地主機(jī)

          基本格式:

          file ://<host>/<path>
          

          示例:

          file://OFFICE-FS/policies/casual-fridays.doc
          

          7、telnet

          方案telnet用于訪問(wèn)交互式業(yè)務(wù)。它表示的不是對(duì)象自身,而是可通過(guò)telnet協(xié)議訪問(wèn)的交互式應(yīng)用程序(資源)

          基本格式:

          telnet://<user>:<password>@<host>:<port>/
          

          示例:

          telnet://slurp:webhound@joes-hardware.com:23/
          

          [注意]除了以上常見的7種方案之外,如果要查看全部的URI方案列表,請(qǐng)移步至https://www.w3.org/Addressing/schemes.html

          【主機(jī)和端口】

          要想在因特網(wǎng)上找到資源,應(yīng)用程序要知道是哪臺(tái)機(jī)器裝載了資源,以及在那臺(tái)機(jī)器的什么地方可以找到能對(duì)目標(biāo)資源進(jìn)行訪問(wèn)的服務(wù)器。URL的主機(jī)和端口組件提供了這兩組信息

          主機(jī)組件標(biāo)識(shí)了因特網(wǎng)上能夠訪問(wèn)資源的宿主機(jī)器。可以用上述主機(jī)名(www.hardware.com)或者IP地址來(lái)表示主機(jī)名

          [注意]IP地址可以是192.168.1.1這類IPv4地址名,還可以是[0:0:0:0:0:0:0:1]這樣用括號(hào)括起來(lái)的IPv6地址名

          比如,下面兩個(gè)URL就指向同一個(gè)資源——第一個(gè)URL通過(guò)主機(jī)名,第二個(gè)通過(guò)IP地址指向服務(wù)器

          http://www.hardware.com:80/index.html 
          http://161.58.228.45:80/index.html
          

          端口組件標(biāo)識(shí)了服務(wù)器正在監(jiān)聽的網(wǎng)絡(luò)端口。對(duì)下層使用了TCP協(xié)議的HTTP來(lái)說(shuō),默認(rèn)端口號(hào)為80

          【用戶名和密碼】

          很多服務(wù)器都要求輸入用戶名和密碼才會(huì)允許用戶訪問(wèn)數(shù)據(jù)。FTP服務(wù)器就是這樣一個(gè)常見的實(shí)例

          ftp://ftp.prep.ai.mit.edu/pub/gnu
          ftp://anonymous@ftp.prep.ai.mit.edu/pub/gnu
          ftp://anonymous:my_passwd@ftp.prep.ai.mit.edu/pub/gnu 
          http://joe:joespasswd@www.joes-hardware.com/sales_info.txt
          

          第一個(gè)例子沒(méi)有用戶或密碼組件,只有標(biāo)準(zhǔn)的方案、主機(jī)和路徑。如果某應(yīng)用程序使用的URL方案要求輸入用戶名和密碼,比如FTP,但用戶沒(méi)有提供,它通常會(huì)插入一個(gè)默認(rèn)的用戶名和密碼。比如,如果向?yàn)g覽器提供一個(gè)FTP URL,但沒(méi)有指定用戶名和密碼,它就會(huì)插入anonymous(匿名用戶)作為你的用戶名,并發(fā)送一個(gè)默認(rèn)的密碼(IE會(huì)發(fā)送IEUser)

          第二個(gè)例子顯示了一個(gè)指定為anonymous的用戶名。這個(gè)用戶名與主機(jī)組件組合在一起,看起來(lái)就像E-mail地址一樣。字符將用戶和密碼組件與URL的其余部分分隔開來(lái)

          在第三個(gè)例子中,指定了用戶名(anonymous)和密碼(my_passwd),兩者之間由字符“:”分隔

          【路徑】

          URL的路徑組件說(shuō)明了資源位于服務(wù)器的什么地方。路徑通常很像一個(gè)分級(jí)的文件系統(tǒng)路徑

          http://www.hardware.com:80/seasonal/index-fall.html 
          

          這個(gè)URL中的路徑為/seasonal/index-fall.html,很像UNIX文件系統(tǒng)中的文件系統(tǒng)路徑。路徑是服務(wù)器定位資源時(shí)所需的信息。可以用字符“/”將HTTP URL的路徑組件劃分成一些路徑段(path segment),每個(gè)路徑段都有自己的參數(shù)(param)組件

          【參數(shù)】

          對(duì)很多方案來(lái)說(shuō),只有簡(jiǎn)單的主機(jī)名和到達(dá)對(duì)象的路徑是不夠的。除了服務(wù)器正在監(jiān)聽的端口,以及是否能夠通過(guò)用戶名和密碼訪問(wèn)資源外,很多協(xié)議都還需要更多的信息才能工作

          負(fù)責(zé)解析URL的應(yīng)用程序需要這些協(xié)議參數(shù)來(lái)訪問(wèn)資源。否則,另一端的服務(wù)器可能就不會(huì)為請(qǐng)求提供服務(wù),或者更糟糕的是,提供錯(cuò)誤的服務(wù)。比如,像FTP這樣的協(xié)議,有兩種傳輸模式:二進(jìn)制和文本形式。肯定不希望以文本形式來(lái)傳送二進(jìn)制圖片,這樣的話,二進(jìn)制圖片可能會(huì)變得一團(tuán)糟

          為了向應(yīng)用程序提供它們所需的輸入?yún)?shù),以便正確地與服務(wù)器進(jìn)行交互,URL中有一個(gè)參數(shù)組件。這個(gè)組件就是URL中的名值對(duì)列表,由字符“;”將其與URL的其余部分(以及各名值對(duì))分隔開來(lái)。它們?yōu)閼?yīng)用程序提供了訪問(wèn)資源所需的所有附加信息。比如:

          ftp://prep.ai.mit.edu/pub/gnu;type=d
          

          在這個(gè)例子中,有一個(gè)參數(shù)type=d,參數(shù)名為type,值為d

          如前所述,HTTP URL的路徑組件可以分成若干路徑段。每段都可以有自己的參數(shù)。比如:

          http://www.hardware.com/hammers;sale=false/index.html;graphics=true
          

          這個(gè)例子就有兩個(gè)路徑段,hammers和index.html。hammers路徑段有參數(shù)sale,其值為false。index.html段有參數(shù)graphics,其值為true

          【查詢字符串】

          很多資源,比如數(shù)據(jù)庫(kù)服務(wù),都是可以通過(guò)提問(wèn)題或進(jìn)行査詢來(lái)縮小所請(qǐng)求資源類型范圍的。假設(shè)數(shù)據(jù)庫(kù)中維護(hù)著一個(gè)未售貨物的清單,并可以對(duì)淸單進(jìn)行査詢,以判斷產(chǎn)品是否有貨,那就可以用下列URL來(lái)査詢Web數(shù)據(jù)庫(kù)網(wǎng)關(guān),看看編號(hào)為12731、顏色為blue、尺寸為large的條目是否有貨:

          http://www.hardware.com/inventory-check.cgi?item=12731&color=blue&size=large
          

          這個(gè)URL的大部分都與我們見過(guò)的其他URL類似。只有問(wèn)號(hào)(?)右邊的內(nèi)容是新出現(xiàn)的。這部分被稱為查詢(query)組件。URL的査詢組件和標(biāo)識(shí)網(wǎng)關(guān)資源的URL路徑組件一起被發(fā)送給網(wǎng)關(guān)資源

          除了有些不合規(guī)則的字符需要特別處理之外,對(duì)査詢組件的格式?jīng)]什么要求。按照常規(guī),很多網(wǎng)關(guān)都希望査詢字符串以一系列“名/值”對(duì)的形式出現(xiàn),名值對(duì)之間用字符“&”分隔

          【片段】

          有些資源類型,比如HTML,除了資源級(jí)之外,還可以做進(jìn)一步的劃分。比如,對(duì)一個(gè)帶有章節(jié)的大型文本文檔來(lái)說(shuō),資源的URL會(huì)指向整個(gè)文本文檔,但理想的情況是,能夠指定資源中的那些章節(jié)

          為了引用部分資源或資源的一個(gè)片段,URL支持使用片段(frag)組件來(lái)表示一個(gè)資源內(nèi)部的片段。比如,URL可以指向HTML文檔中一個(gè)特定的圖片或小節(jié)

          片段掛在URL的右手邊,最前面有一個(gè)字符“#”。比如:

          http://www.hardware.com/tools.html#drills
          

          在這個(gè)例子中,片段drills引用了Web服務(wù)器上頁(yè)面/tools.html中的一個(gè)部分。這部分的名字叫做drills

          HTTP服務(wù)器通常只處理整個(gè)對(duì)象,而不是對(duì)象的片段,客戶端不能將片段傳送給服務(wù)器。瀏覽器從服務(wù)器獲得了整個(gè)資源之后,會(huì)根據(jù)片段來(lái)顯示感興趣的那部分資源

          字符

          URL的設(shè)計(jì)者們認(rèn)識(shí)到有時(shí)人們可能會(huì)希望URL中包含除通用的安全字母表之外的二進(jìn)制數(shù)據(jù)或字符。因此,需要有一種轉(zhuǎn)義機(jī)制,能夠?qū)⒉话踩淖址幋a為安全字符,再進(jìn)行傳輸

          人們?cè)O(shè)計(jì)了一種編碼機(jī)制,用來(lái)在URL中表示各種不安全的字符。這種編碼機(jī)制就是通過(guò)一種“轉(zhuǎn)義”表示法來(lái)表示不安全字符的,這種轉(zhuǎn)義表示法包含一個(gè)百分號(hào)(%),后面跟著兩個(gè)表示字符ASCII碼的十六進(jìn)制數(shù)

          下面是一些例子

          在URL中,有幾個(gè)字符被保留起來(lái),有著特殊的含義。有些字符不在定義的US- ASCII可打印字符集中。還有些字符會(huì)與某些因特網(wǎng)網(wǎng)關(guān)和協(xié)議產(chǎn)生混淆,因此不贊成使用

          下面列出了保留及受限的字符

          常見的三種編碼方法

          【encodeURI()】

          encodeURI()函數(shù)把字符串作為URI進(jìn)行編碼,實(shí)際上enchodeURI()函數(shù)只把參數(shù)中的空格編碼為%20,其余特殊字符均不會(huì)轉(zhuǎn)換

          encodeURI()的不編碼字符有82個(gè):

          ! # $ & ' ( ) * + , - . / : ;=? @ _ ~ 0-9 a-z A-Z
          

          使用方式

          //'http://www.w3school.com.cn<br />'
          console.log(encodeURI("http://www.w3school.com.cn")+ "<br />")
          //'http://www.w3school.com.cn/My%20first/'
          console.log(encodeURI("http://www.w3school.com.cn/My first/"))
          //',/?:@&=+$#'
          console.log(encodeURI(",/?:@&=+$#"))
          

          [注意]encodeURI()可以編碼中文

          //'%E6%B5%8B%E8%AF%95'
          console.log(encodeURI('測(cè)試'));
          

          【decodeURI()】

          decodeURI()函數(shù)可對(duì)encodeURI()函數(shù)編碼過(guò)的URI進(jìn)行解碼。實(shí)際上,decodeURI()僅僅會(huì)把%20轉(zhuǎn)換為空格顯示

          //"http://www.w3school.com.cn/My first/"
          console.log(decodeURI("http://www.w3school.com.cn/My%20first/"));
          

          【encodeURIComponent()】

          encodeURIComponent()函數(shù)可把字符串作為URI組件進(jìn)行編碼。該方法主要對(duì);/?:@&=+$,#等這些用于分隔URI組件的字符以及中文進(jìn)行編碼

          encodeURIComponent不編碼字符有71個(gè):

          !, ',(,),*,-,.,_,~,0-9,a-z,A-Z
          

          由于此方法對(duì):/都進(jìn)行了編碼,所以不能用它來(lái)對(duì)網(wǎng)址進(jìn)行編碼,而適合對(duì)URI中的參數(shù)進(jìn)行編碼

          [注意]encodeURIComponent()可以編碼中文

          var uri="http://www.wrox.com/illegal value.htm#start";
          //'http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start'
          console.log(encodeURIComponent(uri));
          //'%E6%B5%8B%E8%AF%95'
          console.log(encodeURIComponent('測(cè)試'));
          

          【decodeURIComponent()】

          decodeURIComponent()函數(shù)可對(duì)encodeURIComponent()函數(shù)編碼的URI進(jìn)行解碼

          var uri='http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start';
          //'http://www.wrox.com/illegal value.htm#start'
          console.log(decodeURIComponent(uri));
          

          【escape()】

          escape()函數(shù)對(duì)字符串進(jìn)行編碼,將字符的unicode編碼轉(zhuǎn)化為16進(jìn)制序列

          ES3中反對(duì)escape()的使用,并建議用encodeURI和encodeURIComponent代替,不過(guò)escape()依然被廣泛的用于cookie的編碼,因?yàn)閑scape()恰好編碼了cookie中的非法字符并且對(duì)路徑中常出現(xiàn)的“/”不進(jìn)行編碼

          escape()的不編碼字符有69個(gè):

          * + - . / @ _ 0-9 a-z A-Z
          

          [注意]escape()可以編碼中文

          var uri="http://www.wrox.com/illegal value.htm#start";
          //'http%3A//www.wrox.com/illegal%20value.htm%23start'
          console.log(escape(uri));
          //%u6D4B%u8BD5
          console.log(escape('測(cè)試'));
          

          【unescape()】

          unescape()函數(shù)用于對(duì)escape()函數(shù)編碼的URI進(jìn)行解碼

          //http://www.wrox.com/illegal value.htm#start
          console.log(unescape('http%3A//www.wrox.com/illegal%20value.htm%23start'));
          //'測(cè)試'
          console.log(unescape('%u6D4B%u8BD5'));
          

          鏈接文章:

          https://www.cnblogs.com/xiaohuochai/p/6144157.html

          https://www.cnblogs.com/xiaohuochai/p/6144157.html

          https://developer.mozilla.org/zh-CN/docs/Learn/Common_questions/What_is_a_URL

          JS文件添加右鍵菜單,一鍵完成JS混淆加密
          將“JS混淆加密”集成到鼠標(biāo)右鍵菜單
          Windows一鍵JS混淆加密:功能集成到鼠標(biāo)右鍵菜單

          目標(biāo):將“JS混淆加密”功能集成到鼠標(biāo)右鍵菜單,一鍵點(diǎn)擊完成JavaScript代碼混淆加密。

          原因:為什么實(shí)現(xiàn)這個(gè)功能,有什么好處?

          答:方便、易用。JavaScript程序員經(jīng)常需要將代碼進(jìn)行混淆加密。

          操作過(guò)程,通常情況下,需要將代碼復(fù)制或提交到網(wǎng)站或軟件中,以使用JShaman為例,需要復(fù)制代碼到JShaman網(wǎng)站,完成JS混淆加密,再把代碼粘貼回來(lái)。

          JShaman網(wǎng)站不需要注冊(cè)、不需要登錄,打開網(wǎng)站、復(fù)制粘貼就可使用。雖然已經(jīng)很方便,但集成到鼠標(biāo)右鍵菜單可以更方便。

          效果展示:

          實(shí)現(xiàn)方法:

          環(huán)境需求:Node.JS

          1、NodeJS腳本文件準(zhǔn)備

          實(shí)現(xiàn)此功能,需要用NodeJS運(yùn)行一個(gè)腳本JS文件,以便調(diào)用JShaman WebApi接口,進(jìn)行JavaScript混淆加密。

          JS代碼如下,將此文件保存為obfuscate.js,放于任一目錄下:

          /**
           * 調(diào)用JShaman.com WebAPI接口 實(shí)現(xiàn)JavaScript混淆加密
           */
          /**
           * 配置部分
           */
          //JShaman.com VIP碼,免費(fèi)使用設(shè)為"free",如已購(gòu)買VIP碼,在此修改
          const vip_code="free";
          //混淆加密參數(shù)配置,免費(fèi)使用時(shí)無(wú)需配置
          //參數(shù)詳細(xì)說(shuō)明請(qǐng)參見JShaman官網(wǎng),設(shè)為"true"啟用功能、設(shè)為"false"不啟用
          const config={
              //壓縮代碼
              compact: "true",
              //混淆全局變量名和函數(shù)名
              renameGlobalFunctionVariable: "false",
              //平展控制流
              controlFlowFlattening: "true",
              //僵尸代碼植入
              deadCodeInjection: "false",
              //字符串陣列化
              stringArray: "true",
              //陣列字符串加密
              stringArrayEncoding: "false",
              //禁用命令行輸出 
              disableConsoleOutput: "false",
              //反瀏覽器調(diào)試
              debugProtection: "false",
              //時(shí)間限定
              time_range: "false",
              //時(shí)間限定起始時(shí)間、結(jié)束時(shí)間,時(shí)間限定啟用時(shí)此2參數(shù)生效
              time_start: "20240118",
              time_end: "20240118",
              //域名鎖定
              domainLock: [],
              //保留關(guān)鍵字
              reservedNames: [],
          }
          /**
           * 以下代碼實(shí)現(xiàn)向JShaman.com WebApi發(fā)送請(qǐng)求完成JavaScript混淆加密,無(wú)需修改
           */
          const fs=require("fs");
          const readline=require("readline");  
          const request=require("request");
          //獲取命令行參數(shù)中的文件路徑
          //獲取右鍵菜單調(diào)用的文件路徑
          const filePath=process.argv[2];  
          if(!filePath) {  
              console.error("未選中文件");  
              process.exit(1);  
          }  
          //確保文件存在  
          if(!fs.existsSync(filePath)) {  
              console.error(`文件 ${filePath} 不存在`);  
              process.exit(1);  
          } 
          console.log(`正在處理文件:${filePath}`);  
          //從文件中獲取JavaScript代碼
          var javascript_code=fs.readFileSync(filePath,"utf8").toString();
          //Post請(qǐng)求配置
          var options={  
              url: "https://www.jshaman.com:4430/submit_js_code/",  
              method: "POST",  
              json: true,  
              body: {
                  //JavaScript代碼
                  "js_code": javascript_code,
                  //JShaman VIP碼
                  "vip_code": vip_code,
              }
          };  
          //使用free為VIP碼、免費(fèi)調(diào)用JShaman WebAPI接口時(shí),不能配置參數(shù),僅可實(shí)現(xiàn)較低強(qiáng)度代碼保護(hù)
          //如果購(gòu)買了JShaman的VIP碼,則可啟用配置,實(shí)現(xiàn)高強(qiáng)度JavaScript混淆加密
          if(options.body.vip_code !="free"){
              //混淆加密參數(shù)
              options.body.config=config;
          }
          console.log("正在向JShaman.com提交混淆加密請(qǐng)求...")
          //發(fā)送請(qǐng)求到JShaman服務(wù)器,進(jìn)行JavaScript混淆加密
          request(options, function(error, response, body) {  
              if (!error && response.statusCode===200) { 
                  //輸出返回消息
                  console.log(body.message); 
                  //返回狀態(tài)值為0是成功標(biāo)識(shí)
                  if(body.status==0){
                      const rl=readline.createInterface({  
                          input: process.stdin,  
                          output: process.stdout  
                      });
                      rl.question("是否覆蓋原文件?y為是,n則在同目錄下另存。(y/n) ", (answer)=> {  
                          if (answer.toLowerCase()==="y") {  
                              //輸入y,覆蓋原文件  
                              fs.writeFileSync(filePath, body.content.toString());  
                              console.log("文件已覆蓋。");  
                          } else {
                              var obfuscated_file=filePath + ".obfuscated.js";
                              fs.writeFileSync(obfuscated_file, body.content.toString());  
                              console.log("混淆加密后的Js文件:", obfuscated_file);  
                          }  
                          rl.close();  
                      });  
                  }
              } else {  
                  console.error("向JShaman.com發(fā)送請(qǐng)求時(shí)出現(xiàn)錯(cuò)誤:", error);  
              }  
          });
          //按下任意鍵退出程序
          process.on("beforeExit", (code)=> {  
              const rl=readline.createInterface({  
                input: process.stdin,  
                output: process.stdout  
              });  
              console.log("按下任意鍵退出程序...");  
              rl.on("line", (input)=> {  
                rl.close();  
                process.exit(0);  
              });
          }); 
          

          說(shuō)明:此JS腳本默認(rèn)調(diào)用JShaman提供的免費(fèi)Web API接口。JShaman提供有免費(fèi)、商業(yè)兩種接口。如您已獲得JShaman VIP 碼,可修改上述代碼中的VIP碼、使用商業(yè)接口,能使配置參數(shù)生效、獲得更好的JS混淆加密效果。

          2、注冊(cè)表修改

          修改注冊(cè)表是為給JS文件添加右鍵菜單,以便在右鍵點(diǎn)擊.js文件時(shí)菜單中顯示“混淆加密”功能。

          將下面的代碼保存為right_click_menu.reg:

          Windows Registry Editor Version 5.00  
          ; 為 .js 文件類型定義新的上下文菜單項(xiàng)  
          [HKEY_CLASSES_ROOT\SystemFileAssociations\.js\Shell\JavaScript Obfuscate]  
          "MuiVerb"="@shell32.dll,-30525"  
          "Icon"="imageres.dll,-102"
          "Position"="Bottom"  
          ; 定義點(diǎn)擊菜單項(xiàng)時(shí)要執(zhí)行的命令  
          [HKEY_CLASSES_ROOT\SystemFileAssociations\.js\Shell\JavaScript Obfuscate\command]  
          @="\"C:\\Program Files\\nodejs12\\node.exe\" \"C:\\Users\\WangLiwen\\Desktop\\JShaman_JavaScript_Obfuscator\\obfuscate.js\" \"%1\""

          說(shuō)明:“JavaScript Obfuscate”是菜單中的顯示的文字內(nèi)容,可修改。

          保存之后,雙擊將內(nèi)容導(dǎo)入注冊(cè)表:

          僅此兩步,已經(jīng)大功告成,可以使用了。

          JS文件混淆加密測(cè)試:

          測(cè)試,加密一個(gè)JS文件,如上圖所示。

          使用感受:

          如此進(jìn)行“JS文件混淆加密”,非常方便、又快又好!


          主站蜘蛛池模板: 熟女精品视频一区二区三区| 国产亚洲欧洲Aⅴ综合一区| 一区二区三区视频网站| 色综合一区二区三区| 国产丝袜无码一区二区三区视频| 国产成人精品视频一区二区不卡| 亚洲av无码一区二区三区乱子伦| 国产精品日韩欧美一区二区三区| 日本精品夜色视频一区二区| 中文字幕在线看视频一区二区三区| 麻豆精品人妻一区二区三区蜜桃| 精品久久国产一区二区三区香蕉| 精品无码一区二区三区爱欲九九| 大帝AV在线一区二区三区| 日韩精品无码一区二区视频| 亚州国产AV一区二区三区伊在| 亚洲高清日韩精品第一区| 狠狠综合久久AV一区二区三区| 日本精品一区二区三区视频 | 日韩一区精品视频一区二区| 亚洲成人一区二区| 四虎精品亚洲一区二区三区| 国内精品视频一区二区三区八戒| 中文字幕无线码一区二区| 久久免费国产精品一区二区| 人妻AV中文字幕一区二区三区 | 99久久精品日本一区二区免费| 日韩一区二区三区在线精品 | 日韩人妻无码一区二区三区久久99 | 日韩中文字幕一区| 在线观看精品一区| 精品一区二区三区AV天堂| 国产嫖妓一区二区三区无码| 日韩精品一区二区三区在线观看l 日韩精品一区二区三区毛片 | 一区二区三区日本视频| 亚洲熟女少妇一区二区| 久久久av波多野一区二区| 国产视频一区二区| 精品aⅴ一区二区三区| 伊人色综合网一区二区三区| 久久精品成人一区二区三区|