如何在不执行JavaScript或CSS的情况下加载它们?

7

我知道通过在页面的头部或正文中添加<style>或者<link>标签可以实现动态加载脚本和样式表,但这样做会导致浏览器一旦下载就会立即执行。我在思考其他下载但不执行javascript/css代码的方法。首先,我想到了XMLHttpRequest。

//simple execution received script
var executeScript = function(code){
    eval(code);
};
//create XMLHttpRequest in cross-browser manner
var xhr = createXMLHTTPObject();
//check whether file is loaded
var checkStatus = function(){
    if(xhr.readyState  == 4){
        if(xhr.status >= 200 && xhr.status < 300 || xhr == 304){
            executeScript(xhr.responseText);   
        }
        else {//error
        }
    }
};
//do request
xhr.open('get','http://podlipensky.com/examples/dynamicscript/hey.js', true);
xhr.onreadystatechange = checkStatus;
xhr.send(null);

但是由于同源策略(Same Origin Policy),我们在这种情况下受到来自同一个域的脚本的限制(尽管我们可以尝试使用CORS来解决它)

另一种方法,我想到的是在页面中动态添加iframe,然后添加script标签到iframe中,使得脚本一旦下载便会被执行,但它是在另一个页面 - iframe中执行。

还有其他下载但不执行脚本的方法吗?

更新:

下载但不执行javascript/css的一个原因之一是预加载第三方库,但只在需要时使用它们。


9
你所问的其他83个问题中,只有23%得到了令你满意的答案,这是真的吗? - T.J. Crowder
3
仅仅因为 CSS/JavaScript 被下载并不意味着它会立即被执行,这就是方法/类的作用。另外,如果你要使用 AJAX,请使用 jQuery。 - Darcy
1
这里有一种独特的方式,但绝不适用于普通用途 http://blog.nihilogic.dk/2008/05/compression-using-canvas-and-png.html - qw3n
2
保罗:这里的重要问题是为什么?你的最终目标是什么?如果我们知道你的最终目标,我们可以更好地帮助你。 - T.J. Crowder
1
@DavidNguyen - 是的。我想说的是,仅仅因为那些文件被下载了,并不意味着它们必须立即应用。例如,您可以使用JavaScript将CSS类添加到HTML元素中。同样的事情也适用于JavaScript。您可以下载JS文件,但这并不意味着所有函数都会被执行。 - Darcy
显示剩余9条评论
4个回答

4

这比iframe更可靠,因为@TJCrowder在答案中提到了iframe运行脚本的问题。不兼容IE<=8,但链接的帖子解释了IE的另一种方法。 - Kevin Borders

1

你也可以使用一个 iframe,并将脚本 / CSS URL 用作框架的 src(因此根本不会被评估/应用),尽管在这种情况下,您需要确保 JavaScript/CSS 以 Content-Type text/plain 提供,以避免出现关于 < 字符之类的不利情况。虽然如果 iframe src 来自不同的来源,在一个体面的浏览器上,你也应该遇到 SOP 问题。

除此之外,我认为你列出的选项已经基本覆盖了所有情况。


好的,如何将脚本加载到iframe中并不重要,但无论如何还是谢谢您... - Pavel Podlipensky
@PaulPodlipensky:不太明白你的意思。如果你不想在加载时立即执行脚本,那么这个问题就非常重要了,这似乎是你的问题所在。如果你运行它,iframe内的脚本可以做很多事情(比如将浏览器带到完全不同的地方)。如果你想加载而不运行它,那么你如何做就很重要了,对吧? :-) - T.J. Crowder
我的意思是,如果脚本加载到iframe中,它是否执行并不重要-因为它在iframe中无法做很多事情,并且上下文是iframe而不是我的页面。因此,我和你的方法都可行。我只是想知道在这个领域还有什么其他发现... - Pavel Podlipensky
@PaulPodlipensky:我认为没有。 :-) - T.J. Crowder
Crowser只是为了防止 - 不是我;) 我从一开始就点赞了... 再次感谢您的贡献。 - Pavel Podlipensky
@PaulPodlipensky:谢谢,我没想到它不是(无论如何也不会担心)。 :-) 答案有点薄弱,因为它仍然受SOP的限制(只是在标准ajax的不同阶段)。 - T.J. Crowder

0
假设您控制提供页面的服务器,并且想要将相关JS加载到其中,最简单的方法是通过AJAX将URL提交到您的服务器,从那里加载它(例如通过PHP file_get_contents($url);),并将其作为AJAX调用的结果返回。

OP在问题中已经涵盖了这一点。问题是“是否有其他下载脚本而不执行的方法?”(我强调)。 - T.J. Crowder
@T.J.Crowder 我看不到任何关于服务器端处理的 OQ 的部分...你能具体说明一下吗? - Eugen Rieck
OP谈到使用Ajax来检索内容,并谈到了围绕此问题的问题(SOP,CORS等)。如果您的意思是使用自己的服务器作为代理,那么答案对此并不清楚。 - T.J. Crowder
@T.J.Crowder 我的回答只是:通过服务器端处理来解决SOP问题的一种方法。这与直接从页面加载 fundamentally 不同。我不建议使用代理设置,而是使用专门的 AJAX 调用。 - Eugen Rieck
你需要澄清一下。 (这就是代理的作用。) - T.J. Crowder

0

如果您的脚本只是定义了一个函数,那么它可以在不实际运行任何内容的情况下被执行。当然,这需要双方的协作,就像 JSONP 一样。

//jsonp
var result = {/*...*/};

//missingnonp
var f = function(){ /**/ };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接