0

Gmail просто обновила свой контент политики безопасности: http://googleonlinesecurity.blogspot.com/2014/12/reject-unexpected-content-security.htmlGmail политики защиты контента на Chrome расширений

Это бросает ошибку для моего расширения Chrome, который дополняющая GMail. Чтобы быть ясным, мой скрипт содержимого загружает другой скрипт, который размещен на моем сервере. Это позволяет быстро развертывать.

Refused to load the script 'https://<domain-path>.js?' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://talkgadget.google.com/ https://www.googleapis.com/appsmarket/v2/installedApps/ https://www-gm-opensocial.googleusercontent.com/gadgets/js/ https://docs.google.com/static/doclist/client/js/ https://www.google.com/tools/feedback/ https://s.ytimg.com/yts/jsbin/ https://www.youtube.com/iframe_api https://ssl.google-analytics.com/ https://apis.google.com/_/scs/abc-static/ https://apis.google.com/js/ https://clients1.google.com/complete/ https://apis.google.com/_/scs/apps-static/_/js/ https://ssl.gstatic.com/inputtools/js/ https://ssl.gstatic.com/cloudsearch/static/o/js/ https://www.gstatic.com/feedback/js/ https://www.gstatic.com/common_sharing/static/client/js/ https://www.gstatic.com/og/_/js/". 

Это, как я загрузить скрипт из размещенного контента сценария:

var script = document.createElement('script'); 
script.type = 'text/javascript'; 
script.src = 'https://<domain-path>.js'; 
(document.body || document.head || document.documentElement).appendChild(script); 

Любые мысли?

+0

Очевидно, вы можете изменить заголовок ответа csp, используя chrome extension webRequest. Это обходное решение. Однако я не уверен, что это хорошая практика. –

ответ

3

Вы не должны вставлять внешние скрипты в Gmail, так как это замедляет время загрузки страницы и затрудняет проверку других пользователей. И вы должны, конечно, не использовать API webRequest для удаления заголовка Content-Security-Policy, поскольку это снижает безопасность Gmail.

Если вы действительно хотите извлечь и запустить последнюю версию кода в контексте страницы, используйте XMLHttpRequest загрузить сценарий, а затем вставить <script> тег с этим кодом:

// NOTE: Inserting external scripts should be avoided if possible! 
// Do not use this method if your extension can completely function 
// without external scripts! 

// Even if you have to load an external script, make sure that it is loaded over 
// https:, NEVER over http: ! If you insert scripts from http:-URLs, your users' 
// security can be compromised by MITM attacks. 

var x = new XMLHttpRequest(); 
x.open('GET', 'https://example.com/script.js'); 
x.onload = function() { 
    var s = document.createElement('script'); 
    s.textContent = x.responseText; 
    (document.head || document.documentElement).appendChild(s); 
}; 
x.onerror = function() { 
    // Failed to load. Fallback to loading an (old version of your) script 
    // that is bundled with your extension. It must be listed in the 
    // "web_accessible_resources" section in your manifest file. 
    var s = document.createElement('script'); 
    s.src = chrome.runtime.getURL('script.js'); 
    (document.head || document.documentElement).appendChild(s); 
}; 
x.send(); 

Этот метод не требуется директива 'unsafe-inline', поскольку встроенные скрипты, введенные расширениями, обходят политику безопасности содержимого (ref).

+0

Спасибо за примечание! Что делать, если script.js загружает другие скрипты, для целей управления версиями? script.js будет содержать последнее имя файла (версия). @Rob –

+0

@Kevin Измените настройки, чтобы потребовался только один файл, например, с помощью оптимизатора r.js (для проектов AMD) или путем объединения каждой зависимости с вашим основным сценарием. –

+0

Ваше предложение отлично работало. Единственная проблема в том, что, поскольку скрипт встроен, stacktrace показывает @ как источник, а не имя файла. Но это отдельная проблема. –

Смежные вопросы