我正在尝试创建一个可以在每页上运行多个XMLHttpRequests的Firefox扩展。代码如下(我的main函数调用不同URL上的makeRequest)。我的问题是它始终返回(在“alert('Found ...')”(用于调试目的)相同的URL,而不是显示不同的响应。我认为问题是我应该以某种方式将http_request实例传递给alertContents()函数而不是直接使用http_request,但不确定如何或如果这是正确的。谢谢。
function makeRequest(url,parameters) {
http_request = false;
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
http_request.onreadystatechange = alertContents;
http_request.open('GET', url + parameters, true);
http_request.send(null);
}
function alertContents() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
alert('Found: ' + http_request.responseText);
} else {
alert('There was a problem with the request.');
}
}
}
答案 0 :(得分:2)
您的问题是您只有一个http_request标识符,每次调用makeRequest函数时都会重复使用该标识符。这是一个简单的调整: -
function makeRequest(url,parameters) {
var http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
http_request.onreadystatechange = function() {
alertContents(http_request)
};
http_request.open('GET', url + parameters, true);
http_request.send(null);
return http_request;
}
function alertContents(http_request) {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
alert('Found: ' + http_request.responseText);
} else {
alert('There was a problem with the request.');
}
http_request.onreadystatechange = fnNull;
}
}
function fnNull() { };
http_request标识符是每个makeRequest执行的本地标识符。每次使用捕获触发onreadystatechange时,都会将正确的XHR实例传递给alerrContents。
BTW,为什么要将url与参数分开?由于调用者必须确保参数参数正确地进行了url编码,因此它似乎不是一个非常有用的抽象。此外,调用者无论如何都可以简单地传递包含查询字符串的URL。答案 1 :(得分:1)
使用跨浏览器功能可以进一步改进此功能:
function makeRequest(method, url, parameters) {
var http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
// set type accordingly to anticipated content type
http_request.overrideMimeType('text/xml');
//http_request.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
http_request.onreadystatechange = function() {
alertContents(http_request);
}
url += (method=="GET")?parameters:"";
http_request.open(method, url, true);
if (method == "POST") {
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", parameters.length);
http_request.setRequestHeader("Connection", "close");
}
http_request.send((method=="GET")?null:parameters);
}
答案 2 :(得分:0)
是的,您应该使用相同的XMLHttpRequest
。
事实上,尝试使用此代码并查看它是否有效:
function makeRequest(url,parameters) {
http_request = false;
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
http_request.onreadystatechange = function () {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
alert('Found: ' + http_request.responseText);
} else {
alert('There was a problem with the request.');
}
}
};
http_request.open('GET', url + parameters, true);
http_request.send(null);
}
在上面的代码中,我只是将函数直接附加到onreadystatechange
事件。