我正在尝试创建一个chrome扩展程序,该扩展程序将外部源查询为阻止或允许通过特定页面的引用。以下是我的代码的一部分。我是javascript的新手,范围似乎总是让我感到困惑。
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
var http = new XMLHttpRequest();
var url = "http://xxx.xx.xxxx";
var params = "urlCheck="+encodeString_(details.url);
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
guilt = 0;
console.log(guilt);
}else if(http.readyState == 4 && http.status == 404){
guilt = 1;
console.log(guilt);
}
}
http.send(params);
if(guilt == 1){
return {cancel: true};
}else{
return {cancel: false};
}
},
{urls: ["<all_urls>"],
types:["main_frame"]
},
["blocking"]
);
任何帮助将不胜感激!感谢。
答案 0 :(得分:1)
你做不到。
您的代码无法正常工作,因为XHR是异步的;在整个外部函数完成后执行onreadystatechange
。所以guilt
将是未定义的,或者更糟糕的是,陈旧(来自上一个请求)。
有关详细信息,请参阅此标准问题:Why is my variable unaltered after I modify it inside of a function?
但是,如果您尝试解决此问题,您会注意到您无法从异步处理程序中返回响应。
这是故意的:没有功能可以通过,然后再调用(如Messaging API中的sendResponse
),因为Chrome 不会等你。您需要以确定且快速的方式响应阻止呼叫。
如果可选的
opt_extraInfoSpec
数组包含字符串'blocking'
(仅允许特定事件),则同步处理回调函数。这意味着请求被阻止,直到回调函数返回。
您可以尝试使用同步XHR调用来绕过它。这通常不是一个好主意,因为加载远程响应需要很长时间,并且同步XHR被认为是不推荐使用的。即使您将查询限制为"main_frame"
个请求,这仍会为每个加载添加不确定的延迟。
执行此操作的正确方法是从服务器加载一组规则并定期更新,并在发生请求时根据规则的本地副本验证它。这是AdBlock使用的方法扩展。