如果我有这样的脚本标签:
<script
id = "myscript"
src = "http://www.example.com/script.js"
type = "text/javascript">
</script>
我想获取“ script.js”文件的内容。我正在考虑类似的东西,document.getElementById("myscript").text但在这种情况下不起作用。
如果我有这样的脚本标签:
<script
id = "myscript"
src = "http://www.example.com/script.js"
type = "text/javascript">
</script>
我想获取“ script.js”文件的内容。我正在考虑类似的东西,document.getElementById("myscript").text但在这种情况下不起作用。
Answers:
您要获取文件http://www.example.com/script.js的内容吗?如果是这样,您可以使用AJAX方法来获取其内容,前提是该内容与页面本身位于同一服务器上。
您能详细说明您要完成的工作吗?
tl; dr脚本标签不受CORS和同源策略的约束,因此javascript / DOM无法提供对通过<script>标签加载的资源的文本内容的访问,否则它会中断same-origin-policy。
长版本:
大多数其他答案(以及公认的答案)均正确表明,“正确”方式(用于获取通过<script>加载到页面中的javascript文件的文本内容)正在使用XMLHttpRequest来执行另一个单独的附加请求scriptssrc属性中指示的资源,以下简短的javascript代码将演示这些内容。但是,我发现其他答案并未解决获取javascript文件文本内容的问题,即允许访问通过包含的文件内容<script src=[url]></script>会破坏CORS策略,例如,现代浏览器会阻止XHR资源提供访问控制允许来源标头,因此浏览器除受限制之外CORS,不允许其他任何方式获取内容。
使用以下代码(如在其他问题“使用XHR / AJAX”中提到的那样),可以对文档中所有非内嵌脚本标签发出另一个请求。
function printScriptTextContent(script)
{
var xhr = new XMLHttpRequest();
xhr.open("GET",script.src)
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log("the script text content is",xhr.responseText);
}
};
xhr.send();
}
Array.prototype.slice.call(document.querySelectorAll("script[src]")).forEach(printScriptTextContent);
因此,我将不再重复,而是想通过此答案在方面说明为什么
我知道已经有点晚了,但是某些浏览器支持标记LINKrel="import"属性。
http://www.html5rocks.com/zh-CN/tutorials/webcomponents/imports/
<link rel="import" href="/path/to/imports/stuff.html">
对于其余部分,ajax仍然是首选方式。
如果需要src属性的内容,则必须执行ajax请求并查看responsetext。如果您要在其中放置js,则可以通过innerHTML访问它。
是的,就像公认的答案一样,Ajax是做到这一点的方法。如果您不了解细节,则有很多陷阱。如果使用jQuery.load(...),则假定错误的内容类型(用html代替应用程序/ javascript),这可能会由于将不需要的内容<br>放入(scriptNode).innerText等内容而变得混乱。然后,如果使用jQuery.getScript(...),则下载的脚本将立即执行,而这可能不是您想要的(如果有多个文件,则可能会弄乱文件的加载顺序)。
我发现最好jQuery.ajax与dataType: "text"
我在具有框架集的项目中使用了这种Ajax技术,其中框架集和/或多个框架需要相同的JavaScript,以避免服务器多次发送该JavaScript。
这是经过测试且可以正常工作的代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<script id="scriptData">
var scriptData = [
{ name: "foo" , url: "path/to/foo" },
{ name: "bar" , url: "path/to/bar" }
];
</script>
<script id="scriptLoader">
var LOADER = {
loadedCount: 0,
toBeLoadedCount: 0,
load_jQuery: function (){
var jqNode = document.createElement("script");
jqNode.setAttribute("src", "/path/to/jquery");
jqNode.setAttribute("onload", "LOADER.loadScripts();");
jqNode.setAttribute("id", "jquery");
document.head.appendChild(jqNode);
},
loadScripts: function (){
var scriptDataLookup = this.scriptDataLookup = {};
var scriptNodes = this.scriptNodes = {};
var scriptNodesArr = this.scriptNodesArr = [];
for (var j=0; j<scriptData.length; j++){
var theEntry = scriptData[j];
scriptDataLookup[theEntry.name] = theEntry;
}
//console.log(JSON.stringify(scriptDataLookup, null, 4));
for (var i=0; i<scriptData.length; i++){
var entry = scriptData[i];
var name = entry.name;
var theURL = entry.url;
this.toBeLoadedCount++;
var node = document.createElement("script");
node.setAttribute("id", name);
scriptNodes[name] = node;
scriptNodesArr.push(node);
jQuery.ajax({
method : "GET",
url : theURL,
dataType : "text"
}).done(this.makeHandler(name, node)).fail(this.makeFailHandler(name, node));
}
},
makeFailHandler: function(name, node){
var THIS = this;
return function(xhr, errorName, errorMessage){
console.log(name, "FAIL");
console.log(xhr);
console.log(errorName);
console.log(errorMessage);
debugger;
}
},
makeHandler: function(name, node){
var THIS = this;
return function (fileContents, status, xhr){
THIS.loadedCount++;
//console.log("loaded", name, "content length", fileContents.length, "status", status);
//console.log("loaded:", THIS.loadedCount, "/", THIS.toBeLoadedCount);
THIS.scriptDataLookup[name].fileContents = fileContents;
if (THIS.loadedCount >= THIS.toBeLoadedCount){
THIS.allScriptsLoaded();
}
}
},
allScriptsLoaded: function(){
for (var i=0; i<this.scriptNodesArr.length; i++){
var scriptNode = this.scriptNodesArr[i];
var name = scriptNode.id;
var data = this.scriptDataLookup[name];
var fileContents = data.fileContents;
var textNode = document.createTextNode(fileContents);
scriptNode.appendChild(textNode);
document.head.appendChild(scriptNode); // execution is here
//console.log(scriptNode);
}
// call code to make the frames here
}
};
</script>
</head>
<frameset rows="200pixels,*" onload="LOADER.load_jQuery();">
<frame src="about:blank"></frame>
<frame src="about:blank"></frame>
</frameset>
</html>
使用2008年风格的DOM绑定,它宁愿是:
document.getElementById('myscript').getAttribute("src");
document.getElementById('myscript').getAttribute("type");
如果提供了src属性,则要求用户代理忽略该元素的内容,如果您需要从外部脚本访问该元素,则可能是做错了什么。
更新:我看到您已经添加了注释,以表示想要缓存该脚本并在以后使用它。为了什么目的 假设HTTP是缓存友好的,那么浏览器可能已经满足了缓存需求。
我建议这个问题的答案是使用DOM元素的“ innerHTML”属性。当然,如果脚本加载,你就不会需要做一个Ajax调用得到它。
因此Sugendran应该是正确的(不确定为什么他被否决而没有解释)。
var scriptContent = document.getElementById("myscript").innerHTML;
如果脚本元素为:script元素的innerHTML属性应为您提供字符串形式的脚本内容:
olle也给出了答案,但是我认为它被他的建议“糊涂”了,因为他建议首先通过ajax加载它,我认为他的意思是“内联”而不是两者之间。
如果您要在其中放置js,则可以通过innerHTML访问它。
关于此技术的有用性:
在获取“未定义的变量”(我的脚本(例如,来自工具栏或扩展程序的注入错误的脚本)中未包含)后,我一直希望将这种技术用于(JavaScript异常的)客户端错误日志记录-因此我不认为这是一个出路的想法。