1

我玩得很开心

  • 雷迪斯
  • 网盘

我写了这个

#import('dart:html');
#import('dart:json');

class ChatClient {
  XMLHttpRequest listener;
  int parsePosition = 0;

  void connect(){
    this.listener = new XMLHttpRequest();
    this.listener.open("GET", "http://i.target.co.uk:9005/subscribe/test.json", true);
    this.listener.setRequestHeader('Accept', 'application/json');
    this.listener.on.readyStateChange.add(handleData);
    this.listener.send();
  }

  void handleData(Event event){
    print(this.listener.responseText);
    /*
    if (this.listener.responseText != ""){
      Map data = JSON.parse(this.listener.responseText);
      print(data["subscribe"]);
    }
    */
  }
}

void main(){
  ChatClient client = new ChatClient();
  client.connect();
  document.query('#status').innerHTML = 'Loaded!';
}

问题是,每次我发布一些东西时,responseText 的大小都会像这样增长

{"subscribe":["subscribe","test",1]}
{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}
{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}{"subscribe":["message","test","e"]}

现在你无法解析

{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}{"subscribe":["message","test","e"]}

那我该怎么办?你能清除responseText吗?冲洗缓冲区?某物?

编辑:我知道您可以迭代整个字符串或跟踪每个 json 对象的长度,但没有更清洁的方法吗?

编辑:使用新的打印语句

readyStat: 2 status: 200
{"subscribe":["subscribe","test",1]}
readyStat: 3 status: 200
{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}
readyStat: 3 status: 200
4

2 回答 2

1

编辑 2: 这个堆栈溢出问题与 readyState 更改有类似的问题: Ajax readystate 3 (Chrome / IE) - 我正在努力寻求更体面的帮助。


编辑:我想我已经把你带到了花园小路上——ajax 请求的响应状态(3)它仍在加载/接收信息。

这并不直接适用于您的问题,但我觉得这是问题的一部分。

我快速浏览了http://www.w3.org/TR/2006/WD-XMLHttpRequest-20060405/ 我发现:`readyState of type unsigned short, readonly 对象的状态。属性必须是以下值之一:

0 Uninitialized
    The initial value.
1 Open
    The open() method has been successfully called.
2 Sent
    The UA successfully completed the request, but no data has yet been received.
3 Receiving
    Immediately before receiving the message body (if any). All HTTP headers have been received.
What about HEAD requests?
4 Loaded
    The data transfer has been completed.

所以在第 3 阶段,我们responseText持有部分数据。

来自http://jszen.blogspot.co.uk/2005/03/xmlhttp-and-readystate.html

... URI /some/uri 可以建立持久连接,这意味着除非连接被脚本或服务器终止,否则 readyState 将始终为 3(交互式)。根据文档,此时我应该能够从服务器获取不完整的响应,但显然不是......


在 msdn 上,我发现了这个http://msdn.microsoft.com/en-us/library/ie/ms534361(v=vs.85).aspx

您不能调用 responseBody 和 responseText 属性来获取部分结果(readyState = 3)。这样做会返回错误,因为没有完全收到响应。您必须等到收到所有数据。


第一个答案:

void handleData(Event event){
  print(this.listener.responseText);

  int a = this.listener.readyState;
  int b = this.listener.status;
  print("readyStat: $a status: $b");

  if (this.listener.readyState == 4 && this.listener.status == 200) {
    if (this.listener.responseText != ""){
      Map data = JSON.parse(this.listener.responseText);
      print(data["subscribe"]);
    }
  }
}

在接收器对象上,您将拥有一个 readyState 和一个状态。如果您等到这些都处于完成状态,readyState == 4status==200的数据可能会在您完成后完成。

这是未经测试的,因为我没有合适的环境来测试它

于 2012-06-22T12:42:35.817 回答
0

使用的最终解决方案。

  void connect(){
    this.listener = new XMLHttpRequest();
    this.listener.open("GET", "http://i.h.co.uk:9005/subscribe/test", true);
    this.listener.setRequestHeader('Accept', 'application/json');
    this.listener.on.readyStateChange.add(handleData);
    this.listener.send(); 
  }

  void handleData(Event event){
    try {
      Map data = JSON.parse(this.listener.responseText.substring(this.parsePosition));
      this.parsePosition = this.listener.response.length;
      var message = data['subscribe'][2];
      print("Recieved> $message");
    } catch (final e){
    }
  }
于 2012-06-22T15:33:36.710 回答