2

I have a chunk of javascript code that uses jQuery.post to send some data to a .NET app that's using an HttpListener.

Here's the js:

$.post("http://localhost:8080/catch", { name: "John", time: "2pm" },
    function(data) { 
        alert(data);
    });

and the C#:

HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;

StreamReader reader = new StreamReader(request.InputStream);
string s2 = reader.ReadToEnd();
Console.WriteLine("Data received:" + s2);

// Obtain a response object.
HttpListenerResponse response = context.Response;
// Construct a response.
string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
// You must close the output stream.
output.Close();

The post request goes out ok, and the .NET app reads in the data ok, but the JS code doesn't seem to get the response. The callback function to the jQuery.post fires, but data is always undefined.For brevity I have omitted some C# above where I set the prefixes to the listener.

Any ideas why I'm not getting my data back client-side?

EDIT: I should add that when I run the JS with HttpFox running I get Http code 200, 'NS_ERROR_DOM_BAD_URI', which I thought had something to do with the "http://localhost:8080/catch" I was targeting, but when I hit that resource in firefox, i get the HTML response just fine and it registers as a GET, 200.

EDIT: I simplified the response to just 'meow', and this is what fiddler is giving me for the full response:

HTTP/1.1 200 OK
Content-Length: 4
Content-Type: text/html
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 15 Apr 2011 12:58:49 GMT

meow
Hossein
  • 4,097
  • 2
  • 24
  • 46
LoveMeSomeCode
  • 3,888
  • 8
  • 34
  • 48

4 Answers4

1

Don't forget about the same origin policy restriction. Unless your javascript is hosted on http://localhost:8080 you won't to be able to send AJAX requests to this URL. A different port number is not allowed either. You will need to host your javascript file on an HTML page served from http://localhost:8080 if you want this to work. Or have your server send JSONP but this works only with GET requests.

Remark: make sure you properly dispose disposable resource on your server by wrapping them in using statements or your server might start leaking network connection handles.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • This is unlikely to be the offending cause. It seems it is the location of the server – Aliostad Apr 14 '11 at 17:33
  • yeah, it's all local. This JS is actually executing from a firefox extension i'm making. The idea is to right click an interesting URL and send it to a process running on the local machine. I'm trying to automate some very tedious debugging of a web app. So the request does go through ok, and I get the response in the callback, just not with any data. – LoveMeSomeCode Apr 14 '11 at 17:38
  • @LoveMeSomeCode did you try mine? – Aliostad Apr 14 '11 at 17:40
  • @Aliostad yeah, no luck so far. Still getting the callback clientside, but no data. – LoveMeSomeCode Apr 14 '11 at 18:00
1

Don't forget to release the resources by closing the response.

Calling Close on the response will force the response to be sent through the underlying socket and will then Dispose all of its disposable objects.

In your example, the Close method is only called on the Output stream. This will send the response through the socket, but will not dispose any resources related to the response, which includes the output stream you referenced.

// Complete async GetContext and reference required objects
HttpListenerContext Context = Listener.EndGetContext(Result);
HttpListenerRequest Request = Context.Request;
HttpListenerResponse Response = Context.Response;

// Process the incoming request here

// Complete the request and release it's resources by call the Close method
Response.Close();
0

I do not see setting of content-type. Set the content-type to text/html.

response.ContentType = "text/html";
Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • I tried your suggestion but no dice. I set it right before setting ContentLength64. I still get the javascript callback firing and then throwing an error because data is undefined. – LoveMeSomeCode Apr 14 '11 at 17:40
  • Use fiddler to capture the response and update your question. – Aliostad Apr 14 '11 at 17:43
  • good idea, but i installed fiddler 2 and it doesn't seem to work for localhost. I could've sworn there was a firefox extension that showed that stuff. I'll go look around. – LoveMeSomeCode Apr 14 '11 at 18:56
  • ok, now i'm using HttpFox, which seems to work with localhost and it shows a lot. it's telling the HTTP result is 200 and the type is 'NS_ERROR_DOM_BAD_URI'. Any idea what that means? Because of the HttpListener thing I don't really have a 'resource' to hit, I'm just posting to "http://localhost:8080/catch" – LoveMeSomeCode Apr 14 '11 at 19:08
  • I use Fiddler for local stuff too, it works. Have a lok here http://stackoverflow.com/questions/214308/how-do-i-get-fiddler-to-stop-ignoring-traffic-to-localhost – Aliostad Apr 14 '11 at 19:09
  • Sorry, the code is 200 either way. With a firefox request I get 'GET 200 text/plain', with the JS code I get 'POST 200 application/xml(NS_ERROR_DOM_BAD_URI)' - this changes to 'POST 200 text/html(NS_ERROR_DOM_BAD_URI) after your suggestion of changing the contentType. – LoveMeSomeCode Apr 14 '11 at 19:16
  • OK, there seems to be some headers missing or something. Can you output the whole HTTP response? – Aliostad Apr 14 '11 at 19:20
  • Ok, after following your link I got fiddler to report on localhost. It seems to get the response just fine. I changes the .NET code to just return the string 'meow', and in Fiddler, the TextView panel gives 4(newline)meow(newline)0. It says Response is encoded and if I click that button it just changes it to meow. – LoveMeSomeCode Apr 14 '11 at 20:31
  • This is the Raw tab before I click the transform button:HTTP/1.1 200 OK Transfer-Encoding: chunked Server: Microsoft-HTTPAPI/2.0 Date: Thu, 14 Apr 2011 20:31:30 GMT 4 meow 0 – LoveMeSomeCode Apr 14 '11 at 20:32
  • `Transfer-Encoding: chunked Server: Microsoft-HTTPAPI/2.0` here is your problem my friend. – Aliostad Apr 14 '11 at 20:36
  • Yeah, i was just researching that bit. Any idea how to disable it? – LoveMeSomeCode Apr 14 '11 at 20:37
  • Ok, I found a site that says that if I specify the ContentLength64 that it won't be chunked. I had removed that bit for testing, so I put it back in. Now, Fiddler says it's not chunked anymore, no 4, no 0, just my text. But the JS callback still has no data. – LoveMeSomeCode Apr 14 '11 at 20:42
  • Remove `ContentLength64` line. – Aliostad Apr 14 '11 at 20:42
  • Well, it gets weirder. I keep stripping things out, and it turns out even with no call back function at all, HttpFox and Firebug are still telling me the response it bad. But Fiddler sees the text coming back just fine. – LoveMeSomeCode Apr 14 '11 at 20:46
  • Same thing without the ContentLength64. The thing is, the data is apparently coming and going just fine. I think it's something that firefox doesn't like about the response header. I can't alert(data), I can't even have a function with no args that executes. It's like it has a problem running the callback when it gets the response. – LoveMeSomeCode Apr 14 '11 at 20:49
  • Ok, ironically, I think the andwer about the local domain might have something. According to this: http://tycoontalk.freelancer.com/javascript-forum/158783-ns_error_dom_bad_uri-in-firefox.html it might just be firefox complaining that I'm doing an XSS thing to a different domain. Damn. – LoveMeSomeCode Apr 14 '11 at 20:56
  • 1
    WHat is the payload? COme on! would you just paste the response in the question please???? – Aliostad Apr 14 '11 at 20:56
  • That's a lot of punctuation there. When you say payload, do you mean the response payload? If so, it's just 'meow', just a string, no chunking, no 0s 4s or anything else. I think it's a jquery problem. – LoveMeSomeCode Apr 15 '11 at 12:18
  • 1
    OK, I mean just post the data (all of the HTTP response including the headers) formatted as it is. If you output in comments, it will loose all new line characters which are very important. – Aliostad Apr 15 '11 at 12:21
0

You can simplify the writing code a lot. Just use this:

        // Construct a response.
        string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
        context.Response.Write(responseString);

No need for the OutputStream or most of that other code. If you do have a reason to use it, note that you actually should not close the OutputStream. When you use Resopnse.OutputStream you're retrieving a reference to it but you're not taking ownership. It's still owned by the Response object and will be closed properly when the Response is disposed at the end of the request.

Samuel Neff
  • 73,278
  • 17
  • 138
  • 182