Undvika säkerhetsrelaterade JavaScript-fel

Adobe AIR 1.0 och senare

Om du anropar kod som är begränsad från användning i en sandlåda på grund av de här säkerhetsreglerna skickar runtime-modulen ett JavaScript-fel av liknande typ: ”Säkerhetsöverträdelse i Adobe AIR vid körning av JavaScript-kod i programmets säkerhetssandlåda.” Följ de här kodningsrutinerna om du vill undvika det här felet.

Orsaker till säkerhetsrelaterade JavaScript-fel

Kod som körs i programsandlådan är begränsad för de flesta åtgärder som innebär utvärdering och körning av strängar när dokumentets load-händelse har utlösts och eventuella load-händelsehanterare har avslutats. Försök att använda följande typer av JavaScript-programsatser som utvärderar och kör potentiellt osäkra strängar genererar JavaScript-fel:

Mappa programinnehåll till en annan sandlåda

I de flesta fall kan du skriva över eller strukturera om ett program så att säkerhetsrelaterade JavaScript-fel undviks. Om omskrivning eller omstrukturering inte är möjlig kan du dock läsa in programinnehållet i en annan sandlåda med hjälp av den teknik som beskrivs i Läsa in programinnehåll i en icke-programsandlåda. Om det här innehållet också måste ha tillgång till AIR-programmeringsgränssnitten kan du skapa en sandlådebrygga enligt beskrivningen i Konfigurera ett gränssnitt för en sandlådebrygga.

Funktionen eval()

I programsandlådan kan bara funktionen eval() användas innan sidans load-händelse eller under en load-händelsehanterare. När sidan har lästs in kommer inte anrop till eval() att köra koden. I följande fall kan du dock skriva om koden så att den undviker användning av eval().

Tilldela egenskaper till ett objekt

I stället för att tolka en sträng för att skapa egenskapskopplaren:

eval("obj." + propName + " = " + val);

använd egenskaper med hakparenteser:

obj[propName] = val;

Skapa en funktion med variabler som finns i kontexten

Ersätt programsatser enligt följande:

function compile(var1, var2){ 
    eval("var fn = function(){ this."+var1+"(var2) }"); 
    return fn; 
}

med:

function compile(var1, var2){ 
    var self = this; 
    return function(){ self[var1](var2) }; 
}

Skapa ett objekt genom att använda namnet på klassen som en strängparameter

Ta till exempel en hypotetisk JavaScript-klass som definierats med följande kod:

var CustomClass =  
    { 
        Utils: 
        { 
            Parser: function(){ alert('constructor') } 
        }, 
        Data:  
        { 
         
        } 
    }; 
var constructorClassName = "CustomClass.Utils.Parser";

Det enklaste sättet att skapa en instans är att använda eval():

var myObj; 
eval('myObj=new ' + constructorClassName +'()')

Du kan dock undvika anrop till eval() genom att tolka varje komponent av klassnamnet och skapa det nya objektet med hjälp av hakparenteser:

function getter(str) 
{ 
    var obj = window; 
    var names = str.split('.'); 
    for(var i=0;i<names.length;i++){ 
        if(typeof obj[names[i]]=='undefined'){ 
            var undefstring = names[0]; 
            for(var j=1;j<=i;j++) 
                undefstring+="."+names[j]; 
            throw new Error(undefstring+" is undefined"); 
        } 
        obj = obj[names[i]]; 
    } 
    return obj; 
}

Om du vill skapa instansen använder du:

try{ 
    var Parser = getter(constructorClassName); 
    var a = new Parser(); 
    }catch(e){ 
        alert(e); 
}

setTimeout() och setInterval()

Ersätt den sträng som skickas som hanterarfunktion med en funktionsreferens eller ett objekt. Ersätt till exempel en programsats som:

setTimeout("alert('Timeout')", 100);

med:

setTimeout(function(){alert('Timeout')}, 100); 

Om funktionen kräver att objektet this är angett av anroparen kan du ersätta en programsats som:

this.appTimer = setInterval("obj.customFunction();", 100);

med följande:

var _self = this; 
this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);

Funktionskonstruktor

Anrop till new Function(param, body) kan ersättas med en textbunden funktionsdeklaration eller bara användas innan sidans load-händelse har hanterats.

javascript: URL:er

Koden som definierats i en länk med hjälp av javascript: URL-schemat ignoreras i programsandlådan. Inget fel om osäker JavaScript genereras. Du kan ersätta länkar med hjälp av javascript: URL:er som:

<a href="javascript:code()">Click Me</a>

med:

<a href="#" onclick="code()">Click Me</a>

Händelseåterkopplingar som är tilldelade via onevent-attribut i innerHTML- och outerHTML-programsatser

När du använder innerHTML eller outerHTML för att lägga till element i ett dokuments DOM, ignoreras alla händelseåterkopplingar som tilldelats i programsatsen, t.ex. onclick och onmouseover. Inget säkerhetsfel genereras. Du kan i stället tilldela ett id-attribut till de nya elementen och ställa in så att händelsehanterarens återkopplingsfunktioner använder metoden addEventListener().

Ta till exempel ett angivet målelement i ett dokument, såsom:

<div id="container"></div>

Ersätt programsatser som:

document.getElementById('container').innerHTML =  
    '<a href="#" onclick="code()">Click Me.</a>';

med:

document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>'; 
document.getElementById('smith').addEventListener("click", function() { code(); });

Inläsning av JavaScript-filer från plats utanför programmets installationskatalog

Det är inte tillåtet att läsa in skriptfiler från en plats utanför programsandlådan. Inget säkerhetsfel genereras. Alla skriptfiler som körs i programsandlådan måste vara installerade i programkatalogen. Om du vill använda externa skript på en sida måste du mappa sidan till en annan sandlåda. Se Läsa in programinnehåll i en icke-programsandlåda.

document.write() och document.writeln()

Anrop till document.write() och document.writeln() ignoreras efter att sidans load-händelse har hanterats. Inget säkerhetsfel genereras. Du kan också läsa in en ny fil eller ersätta innehållet i dokumentet med hjälp av DOM-ändringstekniker.

Synkrona XMLHttpRequests innan load-händelsen eller under en load-händelsehanterare

Synkrona XMLHttpRequests som startats innan sidans load-händelse eller under en load-händelsehanterare returnerar inget innehåll. Asynkrona XMLHttpRequests kan startas men returneras inte förrän efter load-händelsen. När load-händelsen har hanterats beter sig synkrona XMLHttpRequests normalt.

Dynamiskt skapade skriptelement

Dynamiskt skapade skriptelement som t.ex. är skapade med innerHTML eller metoden document.createElement() ignoreras.