ОТПРАВКА jQuery в .NET HttpListener и обратно

#c# #javascript #http

#c# #javascript #http

Вопрос:

У меня есть фрагмент кода javascript, который использует jQuery.post для отправки некоторых данных в .NET-приложение, использующее HttpListener.

Вот js:

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

и 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();
  

Запрос post выполняется нормально, и .NET app считывает данные нормально, но JS-код, похоже, не получает ответа. Запускается функция обратного вызова jQuery.post, но данные всегда не определены.Для краткости я опустил некоторые C # выше, где я устанавливал префиксы для прослушивателя.

Есть идеи, почему я не получаю свои данные обратно на стороне клиента?

РЕДАКТИРОВАТЬ: Я должен добавить, что когда я запускаю JS с запущенным HttpFox, я получаю Http-код 200, ‘NS_ERROR_DOM_BAD_URI’, который, как я думал, имеет какое-то отношение к «http://localhost:8080/catch » Я настраивал таргетинг, но когда я нажимаю на этот ресурс в Firefox, я получаю HTML-ответ просто отлично, и он регистрируется как GET, 200.

РЕДАКТИРОВАТЬ: Я упростил ответ до простого «мяу», и это то, что fiddler дает мне для полного ответа:

 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
  

Ответ №1:

Не забывайте об ограничении политики того же источника. Если ваш javascript не размещен на http://localhost:8080 , вы не сможете отправлять AJAX-запросы на этот URL. Другой номер порта также не допускается. Вам нужно будет разместить ваш файл javascript на HTML-странице, с которой он обслуживается http://localhost:8080 , если вы хотите, чтобы это работало. Или попросите ваш сервер отправить JSONP, но это работает только с запросами GET.

Примечание: убедитесь, что вы правильно размещаете доступные ресурсы на своем сервере, заключив их в инструкции using, иначе на вашем сервере может начаться утечка дескрипторов сетевого подключения.

Комментарии:

1. Вряд ли это является причиной нарушения. Похоже, это местоположение сервера

2. да, все это локально. Этот JS фактически выполняется из расширения Firefox, которое я создаю. Идея состоит в том, чтобы щелкнуть правой кнопкой мыши интересный URL-адрес и отправить его процессу, запущенному на локальном компьютере. Я пытаюсь автоматизировать очень утомительную отладку веб-приложения. Итак, запрос действительно проходит нормально, и я получаю ответ при обратном вызове, просто без каких-либо данных.

3. @LoveMeSomeCode ты пробовал мой?

4. @Aliostad да, пока безуспешно. Все еще получаю обратный вызов на стороне клиента, но данных нет.

Ответ №2:

Не забудьте освободить ресурсы, закрыв ответ.

Вызов Close для ответа принудительно отправит ответ через базовый сокет и затем удалит все его одноразовые объекты.

В вашем примере метод Close вызывается только в выходном потоке. Это отправит ответ через сокет, но не приведет к удалению каких-либо ресурсов, связанных с ответом, который включает выходной поток, на который вы ссылались.

 // 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();
  

Ответ №3:

Я не вижу настройки content-type. Установите content-type равным text/html .

 response.ContentType = "text/html";
  

Комментарии:

1. Я попробовал ваше предложение, но безрезультатно. Я установил его прямо перед установкой ContentLength64. Я все еще получаю запуск обратного вызова javascript, а затем выдаю ошибку, потому что данные не определены.

2. Используйте fiddler для записи ответа и обновления вашего вопроса.

3. хорошая идея, но я установил fiddler 2, и, похоже, он не работает для localhost. Я мог бы поклясться, что было расширение firefox, которое показывало этот материал. Я пойду осмотрюсь.

4. Какова полезная нагрузка? Давай! не могли бы вы просто вставить ответ в вопрос, пожалуйста????

5. Хорошо, я имею в виду просто опубликовать данные (весь HTTP-ответ, включая заголовки) в том виде, в каком они есть. Если вы выводите в комментариях, будут потеряны все символы новой строки, которые очень важны.

Ответ №4:

Вы можете значительно упростить написание кода. Просто используйте это:

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

Нет необходимости в OutputStream или большей части этого другого кода. Если у вас есть причина использовать его, обратите внимание, что на самом деле вам не следует закрывать OutputStream . При использовании Resopnse.OutputStream вы получаете ссылку на него, но не становитесь владельцем. Он по-прежнему принадлежит Response объекту и будет закрыт должным образом, когда Response он будет удален в конце запроса.