Как читать HTTP-ответ с помощью jQuery ajax из C # TcpListener?

Я создал сервер с TcpListener, который отвечает на каждый запрос как фиктивный HTTP. На стороне клиента я использовал jQuery Ajax, чтобы сделать запрос к этому серверу. Сервер получает успешный запрос и отвечает на него.

Проблема в том, что если я делаю запрос в браузере, набирая адрес, он работает, и я вижу результат. Если я попытаюсь сделать запрос jQuery.ajax (...), тогда ajax завершится с ошибкой. Если я использую инспектор Chrome для мониторинга сети, я вижу, что он не получает даже ответа от сервера. Почему это так?

Моя миссия намного больше, чем этот код, которым я поделюсь с вами. Но ведет себя так же.

.NET C # @ на стороне сервера:

using System;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace Server {

    public class Server
    {
        public static void Main()
        {
            try
            {
                TcpListener tcpListener = new TcpListener(IPAddress.Any, 1234);
                tcpListener.Start();
                while (true)
                {
                    Socket socket = tcpListener.AcceptSocket();

                    DummyServer server = new DummyServer(socket);
                    Thread thrd = new Thread(new ThreadStart(server.Run));
                    thrd.Start();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error..... " + e.StackTrace);
            }
        }
    }
    public class DummyServer
    {
        public DummyServer(Socket socket)
        {
            _socket = socket;
        }

        Socket _socket;

        public void Run()
        {
            try
            {
                // Get stream
                var networkStream = new NetworkStream(_socket);

                // Read from stream and decode to string
                byte[] reqBuffer = new byte[32768];
                int read = networkStream.Read(reqBuffer, 0, reqBuffer.Length);
                string requestString = Encoding.UTF8.GetString(reqBuffer , 0, read);

                Console.WriteLine(requestString);
                Console.WriteLine();

                // Dummy response HTTP
                String responseString =
                    "HTTP/1.1 200 OK\r\n" +
                    "Content-Type: application/json\r\n" +
                    "Content-Length: 15\r\n" +
                    "\r\n" +
                    "{\"test\":\"test\"}";

                Console.WriteLine(responseString);
                Console.WriteLine();

                // Write response
                byte[] respBuffer = Encoding.UTF8.GetBytes(responseString);
                networkStream.Write(respBuffer, 0, respBuffer.Length);
                networkStream.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
                Console.WriteLine(e.Message);
            }
            finally
            {
                // Disconnect and close the socket.
                if (_socket != null)
                {
                    if (_socket.Connected)
                    {
                        _socket.Close();
                    }
                }
            }
        }
    }
}

HTML и jQuery Ajax @ на стороне клиента:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                jQuery.ajax({
                    url: 'http://localhost:1234',
                    type: 'POST',
                    data: JSON.stringify({test: "test"}),
                    dataType: 'text',
                    success: function(result) {
                        $("body").append("nice<br />");
                    },
                    error: function(a, b, c) {
                        $("body").append("damn<br />");
                    }
                });
                $("body").append("done<br />");
            });
        </script>
    </head>
    <body>
    </body>
</html>

Что я делаю не так? Браузер понимает этот ответ, потому что он предназначен для синтаксического анализа html из любого вида s * it?

Edit # 1

Я отлаживал DummyServer, и ajax выдает ошибку в то время, когда я начинаю писать в поток. Даже если я установил параметр тайм-аута для запроса ajax и отлаживаю его шаг за шагом, он дает мне ошибку на том же этапе (ожидание потоковой передачи).

Edit # 2

Когда я пишу заголовки HTTP и данные отдельно, то 2 байта с конца данных теряются после передачи.

Если я напишу весь фиктивный HTTP сразу, они не потеряются. Похоже, что метод NetworkStream.Write записывает дополнительный \ r \ n после данных, которые я ему предоставляю.

// Dummy response HTTP Headers
String responseHeader =
    "HTTP/1.1 200 OK\r\n" +
    "Content-Type: application/json\r\n" +
    "Content-Length: 8\r\n" +
    "\r\n"
// Dummy response data
String responseData =
    "12345678";
//Write header
byte[] respBuffer = Encoding.UTF8.GetBytes(responseHeader );
networkStream.Write(respBuffer, 0, respBuffer.Length);
//Write data
respBuffer = Encoding.UTF8.GetBytes(responseData );
networkStream.Write(respBuffer, 0, respBuffer.Length);
networkStream.Close();

Браузер покажет 123456

// Dummy response HTTP
String responseString =
    "HTTP/1.1 200 OK\r\n" +
    "Content-Type: application/json\r\n" +
    "Content-Length: 8\r\n" +
    "\r\n" +
    "12345678";
//Write Dummy HTTP
byte[] respBuffer = Encoding.UTF8.GetBytes(responseHeader );
networkStream.Write(respBuffer, 0, respBuffer.Length);
networkStream.Close();

Браузер покажет 12345678

Если метод NetworkStream.Write записывает лишние \ r \ n после моих записанных байтов, то не может ли это быть проблемой?

Решение

Вы можно просто использовать jsonp с GET. jQuery.getJSON (url, callback);

Если вам нужен POST, используйте прокси, как показано ниже.

Как вы могли прочитать, существует проблема политики между разными портами и доменами. Лучший способ решить эту проблему - установить какой-нибудь прокси в свой домен и порт. Я сделал свой с помощью php.

Мое общение осуществляется с помощью JSON. На обоих концах моя собственная определенная структура. Итак, я просто пересылаю свой запрос на хост и обратно клиенту. Мне просто нужно установить достаточно большой тайм-аут для ajax.

<?php
    function post_request($data, $referer='') {
        $host = "localhost";
        $port = 7777;

        $fp = fsockopen($host, $port, $errno, $errstr, 5);

        if ($fp){

            // send the request headers:
            fputs($fp, "POST / HTTP/1.1\r\n");
            fputs($fp, "Host: $host\r\n");

            if ($referer != '')
                fputs($fp, "Referer: $referer\r\n");

            fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
            fputs($fp, "Content-length: ". strlen($data) ."\r\n");
            fputs($fp, "Connection: close\r\n\r\n");
            fputs($fp, $data);

            $result = ''; 
            while(!feof($fp)) {
                // receive the results of the request
                $result .= fgets($fp, 128);
            }
        }
        else { 
            return array(
                'status' => 'err', 
                'error' => "$errstr ($errno)"
            );
        }

        // close the socket connection:
        fclose($fp);

        // split the result header from the content
        $result = explode("\r\n\r\n", $result, 2);

        $header = isset($result[0]) ? $result[0] : '';
        $content = isset($result[1]) ? $result[1] : '';

        // return as structured array:
        return array(
            'status' => 'ok',
            'header' => $header,
            'content' => $content
        );
    }

    $req = post_request($_POST['data']); // on jQuery ajax side data must be "data: 'data='+JSON.stringify({test: "test"}),

    header("Content-Type: application/json");
    echo $req['content'];
?>
5
задан vellotis 17 November 2011 в 20:48
поделиться