Eval в приложении chrome package
Я хотел бы создать расширение приложения chrome пакета, чтобы пользователь мог писать и выполнять javascript-код (например, консоль javascript).
Я хотел бы использовать функцию eval()
для выполнения JS-кода.
Классическая функция javascript eval
выдает ошибку при вызове из расширения chrome:
Неисправность Ошибка: генерация кода из строк, запрещенных для этого контекста
Чтобы использовать eval
в расширении chrome, нужно использовать sandbox, но когда я пишу песочницу в манифесте, я получаю эту ошибку:
При попытке установить это расширение были предупреждения. "песочница" не разрешена для указанного типа пакета (тема, приложение и т.д.).
UPDATE
В соответствии с этой проблемой песочницы не поддерживаются для приложений пакетов, поэтому у меня есть два вопроса:
-
Есть ли другой метод, который я могу использовать вместо eval()
?
-
Можно ли использовать eval
без песочницы? (Я думаю, вероятно, не по соображениям безопасности?)
Ответы
Ответ 1
UPDATE:
Поскольку, по крайней мере, с января 2013 года Chrome теперь разрешает директиву unsafe-eval
Content C политики (CSP), которая позволяет выполнять eval
за пределами песочницы:
Политика против eval()
и ее родственников, таких как setTimeout(String)
, setInterval(String)
и new Function(String)
, может быть смягчена добавлением 'unsafe-eval'
к вашей политике
Добавьте подходящий CSP к манифесту расширения, например:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
ошибка, о которой вы говорите в, теперь отмечена fixed
и включена с Chrome 22.
До введения 'unsafe-eval'
не было возможности, чтобы CSP расширения manifest_version: 2
допускал выполнение произвольного текста как кода. В то время Google ясно дал понять, что не было способа удалить это ограничение (вне песочницы):
Встроенный JavaScript, а также опасные методы от типа строки к JavaScript, такие как eval
, не будут выполняться... Нет механизма для ослабления ограничения на выполнение встроенного JavaScript. В частности, установка политики script, которая включает unsafe-inline
, не будет иметь никакого эффекта. Это намеренно.
Как упоминалось выше, это ограничение теперь может быть ослаблено.
Ответ 2
Я предполагаю, что вы говорите о новом упакованном приложении (манифест версии 2), правильно?
Песочницы можно использовать в новых упакованных приложениях абсолютно. На прошлой неделе я просто загрузил образец, который делает именно это: окно отправляет сообщение в скрытый изолированный iframe, iframe компилирует шаблон дескриптора (здесь он мог бы использовать eval вместо) и возвращает скомпилированный HTML на страницу хостинга, которая показывает результат.
Вы также можете проверить этот другой пример, который делает именно то, что вы хотите.
Итак, чтобы прямо ответить на ваши вопросы:
1) Нет, из-за ограничений CSP. Единственный способ оценить динамический JavaScript в приложениях Chrome Packaged - это изолированный iframe. Если это не вариант для вашего приложения, вы также можете отправить и оценить содержимое JavaScript на своем сервере и вернуть только результаты пользователю (хотя это нарушает автономную функцию в Chrome Packaged Apps)
2) Нет, вы можете использовать eval() только в изолированном iframe.
Ответ 3
Вы можете попробовать...
function evalMe(code){
var script = document.createElement('script');
script.innerText = code;
document.querySelector('head').appendChild(script);
}
Это должно создать тот же эффект, если только они не отключили его, но, насколько мне известно, все в порядке. Конечно, если script errors
вы не услышите об этом, если не сделаете некоторую обертку string
до eval
например.
function myHandler(err){
// handle errors.
}
function evalMe(code){
var script = document.createElement('script');
var wrapper = '(function(){ try{ @@ }catch(err){ myHandler(err); } })()';
// Make sure the string has an ending semicolon
code = code[code.length-1] === ';' ? code : code + ';';
script.innerText = wrapper.replace('@@', code);
document.querySelector('head').appendChild(script);
}
В качестве альтернативы вы можете использовать официальный механизм
http://developer.chrome.com/beta/extensions/tabs.html#method-executeScript
Однако для этого вам понадобится справочная страница и используйте сообщение прохождение между вашей страницей app
и фоновой страницей.
UPDATE: Рабочий метод
Вы можете создать похожий метод eval
с использованием iframe и base64
encoded dataURI
, который обрабатывает передачу сообщений между страницей расширения и <iframe>
. Вы можете захватить рабочую копию кода в github. Чтобы просто клонировать или загружать репо и устанавливать "клиент" dir
в качестве неупакованного расширения в хром-расширителе. Код, управляющий плагином, находится в app.js
Использовать iframeEval для проверки, уведомление об ошибке немного ошибочно, но эй, работает eval
.
@appsillers Чтобы ваш плагин работал без какого-либо дополнительного кода, вы можете перезаписать метод eval
на своих расширениях window
с помощью метода iframeEval
в коде.
Ответ 4
Я пришел к этому ответу после того, как приложение Angular.js chrome, которое я запускал, дал ту же ошибку. Автор не упомянул Angular.js, но если кто-то еще сталкивается с этим, вам нужно добавить дополнительную директиву на свою веб-страницу, например.
<html ng-app ng-csp>
...
Это помещает angular в безопасный режим CSP
https://docs.angularjs.org/api/ng/directive/ngCsp
Ответ 5
Вы можете использовать: $scope. $eval() из angular.
Ответ 6
Вот пример того, что НЕ будет работать, поскольку все строки с кодом будут отклонены в приложениях с Chrome:
//To run some code from a string without `eval` just do this:
var code = new Function(yourCodeString);
code();