2016-02-15 61 views
0

我正在編寫基於用戶選擇的圖像操作操作生成縮略圖的代碼,這些操作可能由用戶使用lwip npm程序包模塊選擇的多個操作。在不使用eval的情況下在Node.js中執行js代碼字符串

對於多個動作,lwip提供了批處理功能,然後鏈接其他操作函數。我面臨的問題是用戶可能會選擇任意操作函數的組合,並且檢查所選操作的每個組合都太麻煩。

所以,我有動態生成的代碼js代碼串,我需要執行的功能,無需使用eval,可能危及應用程序安全

下面是我的代碼

'use strict'; 
(function(uploadhandler){ 

    var lwip=require('lwip'), 
     imageSettingProvider=require('../data/imagesettingprovider'), 
     uploadFolder='public/uploads/', 
     imageManipulatorHelper=require('./imagemanipulationactions'), 
     manipulatedImage=''; 

    uploadhandler.generateThumbnail=function(filePath,filename,ImageUploadSetting,fs){ 
     // compound effects 
     var thumbnailPath=''; 

     lwip.open(filePath, function(err, image) { 
      if (err) { 
       console.log(err); 
      }else{ 
       imageSettingProvider.getImageSetting(ImageUploadSetting,{},function(err,imageSettings){ 
        imageSettings.forEach(function(element,index,array){ 
         thumbnailPath=uploadFolder + element.folderName + '/' + filename; 
         var imageAction=element.action; 
         if(imageAction.indexOf(',')>-1){ 
          var imageManipulationActions=imageAction.split(','); 
          var manipulationHtml=''; 
          manipulationHtml += 'image.batch()'; 
          var actionHtml=''; 
          imageManipulationActions.forEach(function(actionelement,actionindex,actionarray){ 
           actionHtml += uploadhandler.PerformMultipleImageManipulation(actionelement,element,actionHtml); 
          }); 
          manipulationHtml += actionHtml; 
          console.log('----------------------------------------------------------------------------------------------------------'); 
          manipulationHtml += '.writeFile(thumbnailPath, function(err) { if (err) throw err;});'; 
          console.log(manipulationHtml); 

         } 
        }); 
       }); 
      } 
     }); 
    }; 


    uploadhandler.PerformMultipleImageManipulation=function(imageAction,imageOpts,actionHtml){ 
     switch (imageAction){ 
      case "crop": 
       actionHtml = '.crop(' + imageOpts.width + ',' + imageOpts.height + ')'; 
       break; 
      case "cropbycoordinates": 
       actionHtml = '.crop(' + imageOpts.cropLeftPos + ',' + imageOpts.cropTopPos + ',' + imageOpts.cropRightPos + ',' + imageOpts.cropBottomPos + ')'; 
       break; 
      case "resize": 
       actionHtml = '.resize(' + imageOpts.width + ',' + imageOpts.height + ')'; 
       break; 
      case "resizecrop": 
       actionHtml = '.resize(' + imageOpts.width + ',' + imageOpts.height + ')' + '.crop(' + imageOpts.width + ',' + imageOpts.height + ')'; 
       break; 
      case "rotate": 
       actionHtml = '.rotate(' + imageOpts.rotateDegree + ',' + imageOpts.backgroundColor + ')'; 
       break; 
      case "blur": 
       actionHtml = '.blur(' + imageOpts.blurVal + ')'; 
       break; 
      case "scale": 
       actionHtml = '.scale(' + imageOpts.scaleVal + ')'; 
       break; 
      case "mirror": 
       actionHtml = '.mirror(' + imageOpts.flipAxes + ')'; 
       break; 
      case "fade": 
       actionHtml = '.fade(' + imageOpts.fadeVal + ')'; 
       break; 
     } 
     return actionHtml; 
    }; 

})(module.exports); 

現在,當我登錄操作變量的控制檯,它給出:

image.batch() 
.resize(480,320) 
.crop(480,320) 
.rotate(75,white) 
.writeFile(thumbnailPath, function(err) { 
if (err) throw err; 
}); 

現在我需要執行上面的js代碼字符串作爲函數生成縮略圖圖像witho ut使用javascript eval函數。

我曾嘗試使用以下方法從sitepoint網站嘗試:

// function we want to run 
var fnstring = "runMe"; 

// find object 
var fn = window[fnstring]; 

// is object a function? 
if (typeof fn === "function") fn(); 

但它給我的錯誤「的ReferenceError:窗口沒有定義 」

請指引我解決這個問題。

+0

您發佈的代碼中沒有任何HTML代碼。 – Pointy

+1

爲什麼你說「html string」而不是「js code string」? – Bergi

+1

如果你想執行動態生成的代碼,'eval'沒有什麼問題。當然,所有其他執行代碼的解決方案都是不安全的。 – Bergi

回答

3

將操作提取到全局對象中並使用每個特定函數的名稱空間執行每一個操作。

var helper = {}; 
helper.b = function() { 
    console.log("foo"); 
} 
helper.c = function() { 
    console.log("bar"); 
} 

//execute them 

function execute(key) { 
    try { 
    helper[key](); 
    } catch (e) { 
    throw new Error("Function does not exist"); 
    } 
} 

execute("b"); 
execute("c"); 
execute("d"); 
+1

當它只是一個命名空間時,你不應該調用那個對象'global'。否則,+1 – Bergi

+0

@Bergi沒錯,我編輯了我的原始答案 – Theodore

相關問題