#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
он будет удален в конце запроса.