2013-05-23 4 views
1

Я прочитал этот вопрос Is it possible to inject a javascript code that OVERRIDES the one existing in a DOM?, и решение работает хорошо, но иногда кажется, что JavaScript-код на странице будет запускаться первым, а затем content_scripts.Проблема при введении кода javascript, который OVERRIDES существует в DOM?

Это приведет к тому, что «OVVERRIDES» не удалось.

Мой тестовый код, как показано ниже:

//manifest.json 
"content_scripts": [ 
{ 
    "matches": ["http://*/*"], 
    "js": ["js_injector.js"], 
    "run_at": "document_start" 
} 

//js_injector.js 
function injectJs(link) { 
var scr = document.createElement('script'); 
scr.type="text/javascript"; 
scr.src=link; 

document.documentElement.appendChild(scr); 
} 
injectJs(chrome.extension.getURL('my.js')); 

//my.js 
console.log("in my.js"); 
function foo() { 
    console.log("in my.js foo"); 
} 

//test.html (view this page in chrome) 
<html> 
<script type="text/javascript"> 
    console.log("I am here 1110"); 
    foo() 
    console.log("I am here 1111"); 
</script> 
</html> 

Обычно я доберусь ниже бревна:

in my.js my.js:114 
I am here 1110 test.html:4 
in my.js foo my.js:116 
I am here 1111 test.html:6 

Но иногда, ниже журналы будут получены:

I am here 1110 test.html:4 
Uncaught ReferenceError: foo is not defined test.html:5 
in my.js test.js:114 

Кажется, что порядок запуска кода на страницах и скрипты содержимого являются случайными? И моя цель позволяет целевым страницам запускать js apis, который определяет в сценариях контента. Кто-нибудь знает, как это исправить? Спасибо!

ответ

0

Я нашел My injected <script> runs after the target-page's javascript, despite using run_at: document_start?, который указал причину и дал решение для работы.

Но очень сложно написать код js в такую ​​строку. Поэтому я написал код python для их чтения и генерации.

import sys 

s_injector_header = """ 
function injectJs(text) { 
    var scr = document.createElement('script'); 
    scr.type="text/javascript"; 
    scr.textContent=text; 
    document.documentElement.appendChild(scr); 
} 

""" 

def openInjector(): 
    fd = open(sys.path[0]+"/js_injector.js","w") 
    fd.write(s_injector_header) 
    return fd 

def closeInjector(fd): 
    fd.close() 

def injectJs(fd,filename): 
    jsfd = open(sys.path[0]+"/"+filename,"r") 
    text = jsfd.read() 
    text = text.replace("\\","\\\\") 
    text = text.replace("'","\\'") 
    text = text.replace('"','\\"') 
    text = text.replace('\n','\\n') 
    fd.write("injectJs('"+text+"');\n\n") 

def main(): 
    fd = openInjector() 
    injectJs(fd,"md5.js") 
    injectJs(fd,"dessrc.js") 
    injectJs(fd,"my_code.js") 
    closeInjector(fd) 

if __name__ == '__main__': 
    main() 
0

Порядок исполнения, безусловно, не является случайным.

Что делает ваша функция injectJS, это создание тега с полем «src» в my.js. Затем вводите это в свой HTML. Что означает my.js включен асинхронно.

Вот что test.html видит:

<script src="my.js"></script>


Из-за этого быть асинхронными, содержимое my.js не всегда загружены, когда вы хотите. Чтобы устранить эту проблему, вы не хотите включать my.js, вы хотите включить содержимое my.js.

Используя Broswerify's brfs, вы можете поместить инструкцию require() в свой код браузера и добавить его фактическое содержимое. После правильных установок, ваш js_injector.js потребуется следующее:

//js_injector.js 

var fs = require('fs'); 

function injectJs(link) { 
    //Create script tag with full file content as the content 
    var scr = document.createElement('script'); 
    link = fs.readFileSync(__dirname + '/inject.js', 'utf-8'); 
    scr.textContent = link; 

    (document.head || document.documentElement).appendChild(src); 
} 

injectJs('my.js'); 

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

//test.html 

<script> 
    console.log("in my.js"); 
    function foo() { 
     console.log("in my.js foo"); 
    } 
</script> 
Смежные вопросы