vel*_*tis 5 c# ajax tcplistener httpresponse httprequest
我用TcpListener创建了服务器,它将每个请求作为虚拟HTTP响应.在客户端,我使用jQuery Ajax向该服务器发出请求.服务器获得成功请求并响应它.
问题是如果我通过输入地址向浏览器发出请求,它可以工作,我可以看到结果.如果我尝试发出jQuery.ajax(...)请求,那么ajax会因错误而失败.如果我使用Chrome检查器来监控网络,我发现它甚至无法从服务器获得响应.为什么会这样?
我的任务比我将与你分享的代码更大.但它的行为相同.
.NET C#@ Server端:
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();
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
HTML和jQuery Ajax @ Client端:
<!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>
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?浏览器理解这个响应,因为它是从每个s*解析html的吗?
我调试了DummyServer,当我开始写入流时,ajax会收到错误.即使我将timeout参数设置为ajax请求并逐步调试它,它也会在同一步骤中给出错误(witing to stream).
当我单独写HTTP Headers和数据时,数据末尾的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();
Run Code Online (Sandbox Code Playgroud)
浏览器将显示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();
Run Code Online (Sandbox Code Playgroud)
浏览器将显示12345678
如果NetworkStream.Write方法在写入的字节之后将额外的\ r \n写入,那么这不是问题吗?
你可以在jET中使用jsonp.jQuery.getJSON(url,callback);
如果您需要POST,请使用Proxy,如下所示.
您可以阅读,不同的端口和域之间存在策略问题.解决问题的最佳方法是将一些代理服务器放入您的域和端口.我用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'];
?>
Run Code Online (Sandbox Code Playgroud)
根据此处的这些附加注释: http: //api.jquery.com/jQuery.get/#notes-0
由于浏览器安全限制,大多数“Ajax”请求都受到同源策略的约束;该请求无法成功检索来自不同域、子域或协议的数据。
您可能会发现这个问题也很有用:jQuery POST to a .NET HttpListener and back Again
归档时间: |
|
查看次数: |
5489 次 |
最近记录: |