【发布时间】:2011-04-13 07:54:38
【问题描述】:
我有一个网站,当用户单击链接时,它使用 XMLHttpRequest 加载信息。系统运行良好,但我希望能够执行在此过程中收集的 JavaScript。
这是一个问题,因为我想“按需”下载脚本,而不是在页面加载时全部加载。
感谢您的帮助
【问题讨论】:
标签: javascript html ajax scripting download
我有一个网站,当用户单击链接时,它使用 XMLHttpRequest 加载信息。系统运行良好,但我希望能够执行在此过程中收集的 JavaScript。
这是一个问题,因为我想“按需”下载脚本,而不是在页面加载时全部加载。
感谢您的帮助
【问题讨论】:
标签: javascript html ajax scripting download
我相信推荐的解决方案是这样的:
function include(scriptUrl)
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", scriptUrl);
xmlhttp.onreadystatechange = function()
{
if ((xmlhttp.status == 200) && (xmlhttp.readyState == 4))
{
eval(xmlhttp.responseText);
}
};
xmlhttp.send();
}
或者类似的东西。
但是,请注意这种方法。它很容易受到跨站点脚本的攻击,这可能会使您(和您的用户)面临各种讨厌的事情。您需要采取适当的预防措施。
【讨论】:
最近我找到了答案(它在 Chrome 中有效,在其他浏览器中未经过测试)。
您可以创建dataURL字符串并将其放入script元素的src属性中。
var xhr = XMLHttpRequest(),
doc = document;
xhr.open('GET', pathToJSFile, true);
xhr.onload = function () {
var script = doc.createElement('script'),
base64 = 'data:application/javascript;base64,';
try {
base64 += btoa(data.responseText);
} catch (e) {
// script file may contain characters that not included in Latin1
var symbols = data.responseText.split('');
for (var i = 0, l = symbols.length; i < l; i++) {
var symbol = symbols[i];
// here we are trying to find these symbols in catch branch
try {
btoa(symbol);
} catch (e) {
var code = symbol.charCodeAt(0).toString(16);
while (code.length < 4) {
code = '0' + code;
}
// replace original symbol to unicode character
symbols[i] = '\\u' + code;
}
}
// create new base64 string from string with replaced characters
base64 += btoa(symbols.join(''));
} finally {
script.src = base64;
// run script
doc.body.appendChild(script);
}
};
xhr.send();
您可以订阅 xhr.onprogress 以显示进度条。
更新。您可以将脚本文件下载为 blob,然后创建 blob-url。
var xhr = XMLHttpRequest(),
doc = document;
xhr.responseType = 'blob';
xhr.open('GET', pathToJSFile, true);
xhr.onload = function () {
var script = doc.createElement('script'),
src = URL.createObjectURL(xhr.response);
script.src = src;
doc.body.appendChild(script);
};
xhr.send();
【讨论】:
您可以使用
运行以字符串形式下载的脚本eval()
不过我建议你添加新的
<script src='..'></script>
到您的文档并有一个回调,它将在下载时调用。有很多 utils 和 jquery 插件。
【讨论】:
eval' 从 XHR 注入比注入 <script> 更危险,因为 XHR 上设置了同源策略(<script> 不存在)。但是,设置<script> 通常更简单。
我在一个移动网络项目上遇到了挑战,神奇的是设置“overrideMimeType”。 这已经过验证,可以在 Android 4.1 到 Android 6.0 上运行。
var head = document.getElementsByTagName('head');
var injectedScript = document.createElement('script');
head[0].appendChild(injectedScript);
var myRequest = new XMLHttpRequest();
myRequest.onreadystatechange = function() {
if (myRequest.readyState == 4 && myRequest.status == 200) {
injectedScript.innerHTML = myRequest.responseText;
//run a function in the script to load it
}
};
function start(){
myRequest.open('GET', 'javascript-url-to-download', true);
myRequest.overrideMimeType('application/javascript');
myRequest.send();
}
start();
【讨论】:
您需要使用 eval 来解析 XHR 中的 javascript,请注意,如果您对 javascript 的来源没有绝对信任,这将非常危险。
【讨论】: