Избежание ошибок безопасности в JavaScript

Adobe AIR 1.0 и более поздних версий

При вызове кода, который в силу ограничений безопасности не может использоваться в изолированной программной среде, среда выполнения отправляет ошибку JavaScript: «Нарушение безопасности среды выполнения Adobe AIR для кода JavaScript в изолированной программной среде приложения». Во избежание этой ошибки следуйте приведенным ниже рекомендациям.

Причины ошибок безопасности JavaScript

Код, выполняемый в изолированной программной среде приложения, не имеет доступа к большинству операций, включая проверку и выполнение строк после выполнения события load и окончания обработки события load . Попытка использовать следующие инструкции JavaScript для проверки и выполнения потенциально опасных строк приведут к ошибкам JavaScript:

Сопоставление содержимого приложения с другой изолированной программной средой

В большинстве случаев, чтобы избежать ошибок безопасности JavaScript, приложение можно переписать или изменить его структуру. Однако когда это невозможно, содержимое приложения может быть загружено в другую изолированную программную среду, как описано в разделе Загрузка содержимого приложения в изолированную программную среду вне приложения . Если этому содержимому также необходим доступ к API-интерфейсам AIR, можно создать мост, как описано в разделе Настройка интерфейса моста изолированной программной среды .

функция eval()

В изолированной программной среде приложения функция eval() может использоваться только до выполнения события load или во время обработки события load . После загрузки страницы вызов eval() не приведет к выполнению кода. Тем не менее в ряде случаев можно переписать код, чтобы не прибегать к функции eval() .

Назначение свойств объекту

Вместо разбора строки для создания средства доступа к свойствам:

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

доступ к свойствам можно получать с помощью обозначений квадратными скобками:

obj[propName] = val;

Создание функции с переменными в контекстном меню

Замените инструкции:

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

на:

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

Создание объекта, использующего имя класса в качестве строкового параметра

Представим некий класс JavaScript, определенный следующим кодом:

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

Самый простой способ создать его экземпляр — функция eval() :

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

Однако можно обойтись и без eval() , если разобрать каждый компонент имени класса и создать новый объект с использованием квадратных скобок:

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; 
}

Экземпляр создается следующим образом:

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

Функции setTimeout() и setInterval()

Замените строку, передаваемую в виде функции обработчика, на ссылку или объект функции. Например, замените инструкцию:

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

на:

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

Или, когда требуется, чтобы в качестве вызывающего объекта функции использовался объект this замените инструкцию:

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

на:

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

Конструктор функции

Вместо вызова new Function(param, body) можно воспользоваться встроенным объявлением функции. Другой вариант — этот вызов можно осуществить до обработки события load .

javascript:URL

Код, определенный в строке с помощью схемы URL-адресов «javascript:», игнорируется в изолированной программной среде. Ошибка безопасности JavaScript не генерируется. Ссылки можно замещать с использованием схемы «javascript: URL», например можно заменить код:

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

на:

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

Обратные вызовы событий, назначаемые атрибутом onevent в инструкциях innerHTML и outerHTML

При использовании innerHTML или outerHTML для добавления элементов в модель DOM документа все обратные вызовы событий, назначенные в инструкции, например onclick или onmouseover , игнорируются. Ошибка безопасности не генерируется. Вместо этого можно назначить атрибут id новым элементам и задать функции обратного вызова обработчика события с помощью метода addEventListener() .

Например, если целевой элемент является документом, как показано ниже:

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

Можно заменить инструкции следующим образом:

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

на:

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

Загрузка файлов JavaScript извне приложения в установочный каталог приложения

Загрузка файлов сценариев извне изолированной программной среды приложения запрещена. Ошибка безопасности не генерируется. Все файлы сценариев, работающие в изолированной программной среде приложения, необходимо установить в каталог приложения. Чтобы использовать на странице внешние сценарии, необходимо сопоставить ее с другой изолированной программной средой. См. раздел Загрузка содержимого приложения в изолированную программную среду вне приложения .

Методы document.write() и document.writeln()

Вызовы методов document.write() и document.writeln() игнорируются после обработки события load для данной страницы. Ошибка безопасности не генерируется. В качестве альтернативы можно загрузить новый файл или заменить «тело» (элемент body) документа, пользуясь методиками работы с DOM.

Синхронные запросы XMLHttpRequest до события load или во время обработки события load

Синхронные запросы XMLHttpRequest, инициированные до обработки события load страницы или во время обработки события load , не возвращают никакого содержимого. Асинхронные запросы XMLHttpRequest могут инициироваться, но ничего не возвращают, пока не будет завершено событие load . После обработки события load синхронные XMLHttpRequest работают как обычно.

Динамически создаваемые элементы сценариев

Динамически создаваемые элементы сценариев (например, с помощью innerHTML или метода document.createElement() ) игнорируются.