【发布时间】:2016-11-23 09:53:02
【问题描述】:
这就是我们的场景...我们要做的第一件事是,我们附加一段 javascript 代码,它将外部脚本添加到文档中,如下所示:
(function() {
var e = document.createElement('script'); e.type = 'text/javascript'; e.async = true; e.src = 'http://blabla.com/script.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(e, s);
})();
然后在script.js 发生以下情况:
function ajaxCall() {
//... some script to send ajax request which calls createDiv() after success
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
else{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4&&xmlhttp.status==200){
createDiv(xmlhttp.responseText);
}
};
xmlhttp.open("GET","http://blabla.com/api/");
xmlhttp.send();
}
function parseResponse(response) {
var parser = new DOMParser();
var dom = parser.parseFromString(response, "text/html");
return dom;
}
function createDiv(responsetext)
{
var dom = parseResponse(responsetext);
var _ws = dom.getElementById('styles');
var h = document.getElementsByTagName('head')[0];
h.appendChild(document.importNode(_ws, true));
var _jr = dom.getElementById('script1').outerHTML;
var _vc = dom.getElementById('script2').outerHTML;
var _rv = dom.getElementById('script3').outerHTML;
var _rw = dom.getElementById('my_div');
var _b = document.getElementsByTagName('body')[0];
var _d = document.createElement('div'); _d.id = 'just_id';
_d.innerHTML = _jr + _vc + _rv;
_d.appendChild(document.importNode(_rw, true));
_b.appendChild(_d);
}
ajaxCall();
一切正常,脚本和 div 正在按预期和预期的位置附加,但附加的脚本不会被执行并且不会影响附加的 div。这是为什么?我怎样才能让它执行?我们也没有在控制台中收到任何警告/错误。使用最新的 Firefox。
编辑 1
评论:你展示的示例脚本只是定义了函数,但它从未真正调用它们
它实际上调用了一个发出ajax请求的函数,请检查编辑的代码sn-p。
编辑 2
评论:您是否尝试过将逻辑放在回调中,然后在 createDiv 中调用它?可能会添加一些日志来测试它是否被调用但它无法找到 div
我刚刚尝试在createDiv() 函数附加的脚本之一中调用console.log('hello world');,但它什么也没做。
编辑 3
了解更多详情。加载页面时,我可以看到
<script type="text/javascript" id="script1" src="http://blabla.com/script1.js"></script>
<script type="text/javascript" id="script2" src="http://blabla.com/script2.js"></script>
<script type="text/javascript" id="script3" src="http://blabla.com/script3.js"></script>
<div id="just_id">Content here</div>
在 DOM-Inspector 中,如上所述,有 console.log('hello world'); 对其进行测试,但它没有被执行。
编辑 4
通过createDiv() 函数向文档的<head></head> 添加了一些CSS,它影响了我的id 为“just_id”的div。 JS 还是不行。
编辑 5
还尝试在我的函数中附加内联 JavaScript 而不是外部 JavaScript,但仍然没有成功。可以在 DOM-Inspector 中看到以下内容,但代码没有记录任何内容。
<script type="text/javascript">
console.log('test');
</script>
编辑 6
我也尝试从 suggested here 导入节点
此方法不允许在不同文档之间移动节点。如果要从不同的文档追加节点,则必须使用 document.importNode() 方法。
并且还尝试更改顺序。 1.css 2.div 3.js 这样但仍然没有成功......有人知道这里发生了什么吗?
检查上面的代码
编辑 7
按照How do you execute a dynamically loaded JavaScript block? 中的建议,我将 div 的 innerHTML 设置为脚本 + 内容,然后像这样附加到 DOM:
检查上面的代码
但还是没有成功。
编辑 8
添加了ajax功能代码。 xmlhttp.open("GET","http://blabla.com/api/"); 中的第三个参数 true(异步)和 false(同步)已经尝试过了。还是没有成功。
编辑 9
函数createDiv() 答案中的建议:
var dom = parseResponse(responsetext);
var _jr = dom.getElementById('script1'); //<script> tag with src attribute
var _vc = dom.getElementById('script2'); //inline <script> for test purposes only, it should actualy be external script also
var _rv = dom.getElementById('script3'); //inline <script>
var _rw = dom.getElementById('external_div');
var _b = document.getElementsByTagName('body')[0];
var _d = document.createElement('div'); _d.id = 'internal_div';
_d.appendChild(document.importNode(_rw, true));
_d.appendChild(document.importNode(_jr, true));
_d.appendChild(document.importNode(_rv, true)); //without second parameter TRUE, I dont get script content
_d.appendChild(document.importNode(_vc, true)); //without second parameter TRUE, I dont get script content
_b.appendChild(_d);
不起作用。只有当我从其他文档中获取内联脚本的innerHTML,创建答案中建议的元素,设置它们的innerHTML,然后附加当前文档时才有效。外部脚本根本不会加载。
编辑 10
.htaccess 来自本地主机...:
<Files *.html>
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Files>
<Files *.php>
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Files>
<Files index.php>
Order Allow,Deny
Allow from all
</Files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /page1/
#RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
</IfModule>
.htaccess from 192.*** ... :
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /direktexpress/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /page2/index.php [L]
</IfModule>
# END WordPress
编辑 11
所以我可能会赏金@Drakes,只是为了努力和他在我的问题上花费的时间,并会显示一些屏幕截图正在发生的事情。这绝对是firefox的bug,我刚刚在chrome上测试过,它可以工作。
第一张图:192.168.2.197/testing/whatever/etc的源代码。 .htaccess 和上面的例子一样
第二张图是script.js的源代码,正在192.168.2.197/testing/whatever/etc上加载。 .htaccess 和上面的例子一样:
第三张图是inspector的截图,我的dom是什么样子的:
第四张图片....什么也没有发生。只是一个与我的问题无关的警告(我希望如此),因为即使我删除了所有脚本,它仍然会出现。
它是 Firefox 的错误吗?
【问题讨论】:
-
很可能是由于Same-origin policy
-
@hindmost 但这应该会给出警告/错误消息。
-
语法错误的错误消息仅适用于同源脚本。 (source)
-
如果脚本中有 syntax 错误,你是对的。但是当由于同源策略而无法加载脚本时,它仍然会显示警告/错误消息。
-
@kso:您展示的示例脚本只是定义函数,但它从未真正调用它们。
标签: javascript html dom