我修改了Bamar建议的代码。我现在使用实例变量来保存回调函数。但是,问题仍然存在,每个makeRequest()
调用都使用相同的回调函数。
我在JavaScript中创建了一个http客户端,它适用于同步GET和POST调用,但如果我使用具有两个或更多回调函数的异步请求,则会为每个请求调用相同的函数。
Service.aspx文件只是中继参数名称的值,因此应该针对每个请求进行更改。
以下是JavaScript代码:
//-- Usage examples ----------------------------------------------
/*
//Full
client = new httpClient();
client.method("get");
client.baseUrl("Service.aspx");
client.requestData({name: "John", age: 56, location: "Kansas City"});
var response = client.makeRequest();
alert(response);
//Multiple requests
client = new httpClient();
client.baseUrl("Service.aspx");
client.requestData("?q=foo");
var data = client.makeRequest();
alert(data);
client.requestData("?q=foobar");
var data = client.makeRequest();
alert(data);
//Minimal
client = new httpClient();
client.baseUrl("Service.aspx?q=test");
client.makeRequest();
//Minimal, with deafult base URL http://localhost/
client = new httpClient();
client.requestData("?q=foobar");
client.makeRequest();
//Full, with response output contained in an object
client = new httpClient();
client.method("get");
client.baseUrl("Service.aspx");
client.requestData("?q=test");
var requestObject = client.makeRequestObject();
alert(requestObject.MimeType);
alert(requestObject.charset);
//Custom callback function to handle asychronous httprequests
myCallback = function (response) {
document.getElementById("div").innerHTML += response;
}
client = new httpClient();
client.asynchronous(true);
client.method("get");
client.baseUrl("Service.aspx");
client.callback(myCallback);
client.requestData({ name: "Peter", age: 45, location: "Kansas City" });
client.makeRequest();
*/
function httpClient() {
this.$baseUrl = "http://localhost/";
this.$method = "get";
this.$requestData = "";
this.$asynchronous = false;
this.$callbackFunction = "";
this.$invokeCallback = function (func, response) {
func(response);
}
}
httpClient.prototype.method = function (requestMethod) {
this.$method = requestMethod;
}
httpClient.prototype.baseUrl = function (requestBaseUrl) {
this.$baseUrl = requestBaseUrl;
}
$_xmlhttpConstruct = function () {
var xmlhttp;
if (window.XMLHttpRequest) {//IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
else {//IE6, IE5
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
catch (e) { }
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
catch (e) { }
try { return new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) { }
}
}
httpClient.prototype.setRequestHeader = function (header, value) {
}
httpClient.prototype.callback = function (func) {
this.$callbackFunction = func; //Does not get set to new callback function on multiple requests
}
httpClient.prototype.asynchronous = function (boolean) {
this.$asynchronous = boolean;
}
httpClient.prototype.makeRequest = function () {
//Initializing the xmlhttp object
var xmlhttp = $_xmlhttpConstruct();
if (this.$requestData == undefined) {
xmlhttp.open(this.$method, this.$baseUrl, this.$asynchronous);
}
else {
if (this.$method == "post") {
xmlhttp.open(this.$method, this.$baseUrl, this.$asynchronous);
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.setRequestHeader("Cache-Control", "no-cache, must-revalidate"); //HTTP 1.1
//xmlhttp.setRequestHeader("Pragma", "no-cache"); //HTTP 1.0
//xmlhttp.setRequestHeader("Expires", "Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
xmlhttp.send(this.$requestData);
invokeCallback = this.$invokeCallback;
callbackFunction = this.$callbackFunction;
if (this.$asynchronous) {
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//Callback
invokeCallback(callbackFunction, xmlhttp.responseText);
}
}
}
else {
return xmlhttp.responseText;
}
//alert("URL: " + this.$baseUrl + "\n" + "Method: " + this.$method + "\n" + "Request data: " + this.$requestData);
}
if (this.$method == "get") {
xmlhttp.open(this.$method, this.$baseUrl + this.$requestData, this.$asynchronous);
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xmlhttp.setRequestHeader("Cache-Control", "no-cache, must-revalidate"); //HTTP 1.1
//xmlhttp.setRequestHeader("Pragma", "no-cache"); //HTTP 1.0
//xmlhttp.setRequestHeader("Expires", Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
xmlhttp.send(null);
invokeCallback = this.$invokeCallback;
callbackFunction = this.$callbackFunction;
if (this.$asynchronous) {
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//Callback
invokeCallback(callbackFunction, xmlhttp.responseText);
}
}
}
else {
return xmlhttp.responseText;
}
//alert("URL: " + this.$baseUrl + "\n" + "Full request URL: " + this.$baseUrl + this.$requestData + "\n" + "Method: " + this.$method + "\n" + "Request data: " + this.$requestData);
}
}
}
httpClient.prototype.requestData = function (data) {
this.$requestData = "";
if (typeof (data) == "object") {
var i = 0;
for (key in data) {
if (i == 0) {
if (this.$method == "get") {
this.$requestData += "?" + key + "=" + data[key];
}
if (this.$method == "post") {
this.$requestData += key + "=" + data[key];
}
i++;
}
else {
this.$requestData += "&" + key + "=" + data[key];
}
}
}
else {
this.$requestData = data;
}
}
以下是我如何使用客户端(异步):
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="httpClient.js"></script>
</head>
<body>
<form id="form1">
<div id="debug"></div>
</form>
<script type="text/javascript">
//Custom callback functions to handle asychronous httprequests
function testone(response) {
document.getElementById("debug").innerHTML += "<div style='color: green;'>" + response + "</div>";
}
function testtwo(response) {
document.getElementById("debug").innerHTML += "<div style='color: red;'>" + response + "</div>";
}
clientOne = new httpClient();
clientOne.asynchronous(true);
clientOne.method("get");
clientOne.baseUrl("Service.aspx");
clientOne.callback(testone);
clientOne.requestData({ name: "Peter", age: 45, location: "Kansas City" });
clientOne.makeRequest();
//---------------------------------------------------
clientTwo = new httpClient();
clientTwo.asynchronous(true);
clientTwo.method("get");
clientTwo.baseUrl("Service.aspx");
clientTwo.callback(testtwo);
clientTwo.requestData({ name: "Mary", age: 45, location: "Kansas City" });
clientTwo.makeRequest();
//Synchronous works!
/*
client = new httpClient();
client.asynchronous(false);
client.method("get");
client.baseUrl("Service.aspx");
client.requestData({ name: "Peter", age: 45, location: "Kansas City" });
testone(client.makeRequest());
client.requestData({ name: "Mary", age: 45, location: "Kansas City" });
testtwo(client.makeRequest());
*/
</script>
</body>
</html>
答案 0 :(得分:1)
您需要为每个并发的AJAX调用使用单独的httpClient
对象。
client1 = new httpClient();
client1.asynchronous(true);
client1.method("get");
client1.baseUrl("Service.aspx");
client1.callback(testone);
client1.requestData({ name: "Peter", age: 45, location: "Kansas City" });
client1.makeRequest();
client2 = new httpClient();
client2.asynchronous(true);
client2.method("get");
client2.baseUrl("Service.aspx");
client2.callback(testtwo);
client2.requestData({ name: "Mary", age: 45, location: "Kansas City" });
client2.makeRequest();
在httpClient
类中,您需要使回调函数成为实例变量,而不是全局变量,因此$_callbackFunction
的所有使用都应为this.$_callbackFunction
。
答案 1 :(得分:0)
document.getElementById("debug").innerHTML += "<div style='color: green;'>" + response + "</div>";
请注意此处的XSS,以防未正确转发响应。 最好使用document.createElement()和document.createTextNode()。