只获取执行此操作的页面代码的副本不是一个好主意。
考虑:您收到内容安全策略错误,因为您正尝试从远程服务器执行一段代码。虽然您可以放宽政策,但让我先解释一下为什么这是一个安全问题。
目前,您的代码加载http://dota2.cyborgmatt.com/prizetracker/data/ti4.json
并执行其内容,而不验证它们是什么。现在它看起来像这样:
populatePrizePool({"dollars":3129676});
但是:这是一个您无法控制的网站。
想象一下:您编写了您的扩展程序,它变得流行,网站管理员注意到异常流量,更改他们的代码以改为加载http://dota2.cyborgmatt.com/prizetracker/data/ti4_.json
,并在谷歌搜索后将原始链接的内容替换为:
alert("By the way, Ramana Venkata is stealing our data. Sincerely, cyborgmatt.com");
突然,您的扩展程序不起作用,您有一群愤怒的用户,并且有点尴尬。
你看到问题了吗?情况可能更糟,因为替换代码可能与 JS 允许的一样邪恶。由于 HTTP 流量很容易拦截,因此 cyborgmatt.com 管理员甚至不需要在您的扩展程序中注入任意代码,这就是为什么甚至不可能以这种方式放宽策略的原因。
现在,来解决问题。而不是 AJAX 加载代码,您应该只加载这个文件,解析它以获取 JSON 数据(即{"dollars":3129676}
),安全地解析和验证该数据,然后才使用它。这样一来,如果发生上述情况,至少不会有什么坏事发生。
第一步:获取数据。
$.ajax
用 XHR替换调用:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
parseAndValidate(xhr.responseText);
}
};
xhr.open("GET", "http://dota2.cyborgmatt.com/prizetracker/data/ti4.json", true);
xhr.send();
第 2 步:解析和验证。
您有一个字符串,您希望其具有以下格式:populatePrizePool(SOME_JSON);
,并且您希望 JSON 数据包含一个非负数dollars
。
function parseAndValidate(str){
var some_json;
// First, extract `SOME_JSON` with a regular expression:
if(str.match(/populatePrizePool\((.*)\);/)) {
some_json = str.match(/populatePrizePool\((.*)\);/)[1];
} else {
throw Error("Unexpected format for ti4.json");
}
// Second, _safely_ parse `some_json`:
var data = JSON.parse(some_json); // Will throw an exception if something's not right
// Third, ensure that the JSON has the required data:
if( !data.dollars || typeof data.dollars !== "number" || data.dollars < 0) {
throw Error("Unexpected data format for ti4.json");
}
// Finally, call the function:
populatePrizePool(data);
}
对于您的小项目来说,这可能有点矫枉过正,但这是一种学习体验。不要盲目相信你无法控制的数据,更不要相信你无法控制的代码。