scaevity
scaevity

Reputation: 4091

Javascript XMLHttpRequest -- only the first POST request works

I'm working on Javascript code that uses XMLHttpRequest to POST to a server.

My code looks something like the following (and I'm running it from a bookmarklet in google chrome):

 var a = sometext; 
 var b = someOtherText; 
 var msg = "a=" + encodeURIComponent(a) + "&b=" + encodeURIComponent(b);
 var server = new XMLHttpRequest();
 server.open("POST", "http://localhost:3333", true);
 server.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 server.send(msg);

I'm listening in on port 3333 of my computer (windows 7) using netcat. The first time I run the code it works fine and the command prompt that is running netcat displays the POST request, all the headers, and the correct value for the sent data (msg). However, when I run the script again (on any open webpage) I no longer see any new information in the command prompt, which I assume means that the later POST commands failed (although when I look at the JavaScript Console in Chrome there are no error messages). If I restart the netcat listener and rerun the script, once again the first run will work correctly and subsequent runs will do nothing.

Any ideas on why this fails?

EDIT: I've done a bit more messing around, and it turns out the connection to localhost does not appear to be being closed (or is somehow being reserved for the server object). If I close the tab that I ran the script on it frees up whatever resources were being held and the script again works.

Is there any way to tell the XMLHttpRequest to close as soon as it is done? I tried adding a header to do that ('Connection: close'), but it turns out that it not allowed. I also tried changing the request to synchronous and calling server.abort() afterwards (I couldn't find great documentation to even say what exactly that function does), but it didn't help. I can't figure out how to specify that I'd like to connect using HTTP/1.0 instead of 1.1, which seems like it might help.

Any ideas?

Upvotes: 0

Views: 1718

Answers (1)

Joel Purra
Joel Purra

Reputation: 25087

You say closing netcat and restarting it works. Perhaps your haven't set up netcat to reopen the listener after the first POST has been disconnected.

According to this netcat cheat sheet, you can use -L on windows.

-L: Listen harder (supported only on Windows version of Netcat). This option makes Netcat a persistent listener which starts listening again after a client disconnects

If you want to close the connection (it's not closed automatically, until perhaps the browser times out), try responding with a valid HTTP response, perhaps the minimal Full-Response "HTTP/1.0 200 OK\r\n\r\n").

Responding with HTTP/1.0 to a HTTP/1.1 request should work as browsers (clients) are assumed to implement the older protocol (they are made to be backwards compatible). You could respond with an HTTP/1.1 response too, but connections are assumed to be persistent (that is, not closed right away).

unless otherwise indicated, the client SHOULD assume that the server will maintain a persistent connection, even after error responses from the server.

Edit: made a mistake and used the minimal request, not response. The response might actually be harder to implement as a persistent listener, since the server might have to close the (TCP) connection. Perhaps a script that recreates the netcat "minimal HTTP listener" (not using -L, but looping to reopen the connection) might work better? The next step is to start an actual HTTP server that serves dummy responses - which is not a bad idea, since it'll give the opportunity to test some well-formed responses with content.

Upvotes: 2

Related Questions