Javascript sinon.js 1.10、jquery 2.1和同步请求

Javascript sinon.js 1.10、jquery 2.1和同步请求,javascript,jquery,ajax,sinon,Javascript,Jquery,Ajax,Sinon,我尝试用sinon.js模拟服务器,并用jQuery.ajax调用它。但我不能让它工作 代码如下: $(function() { var server = sinon.fakeServer.create(); server.respondWith('POST', '/some/test', [200, { 'Content-Type' : 'application/json'}, JSON.stringify({ id : 'test', value : 'test'

我尝试用sinon.js模拟服务器,并用
jQuery.ajax
调用它。但我不能让它工作

代码如下:

$(function() {
  var server = sinon.fakeServer.create();

  server.respondWith('POST', '/some/test', [200, { 'Content-Type' : 'application/json'}, JSON.stringify({
    id : 'test',
    value : 'test'
  })]);

  var success = sinon.spy(),
      error = sinon.spy();

  jQuery.ajax({
    url : '/some/test',
    async : false,
    type : 'POST',
    data : JSON.stringify({
      test : 'test'
    }),
    contentType : 'application/json',
    success : success,
    error : error,
  });

  console.log(server.requests[0].status);
  console.log(server.requests[0].method);
  console.log(server.requests[0].url);
  console.log(server.requests[0].requestBody);

  console.log(success.called);
  console.log(error.called);

  server.restore();
});
如果您尝试此代码,您将看到以下输出:

200
POST
/some/test
{"test":"test"}
false
false
根据前4条日志,sinon对请求进行了响应。但是jQuery从未调用成功回调(也没有调用错误)。
这就像jQuery ajax请求从未完成一样。

问题来自于使用jQuery 2.1的sinon.js:

jQuery 2.1发出如下同步ajax请求:

var req = new XMLHttpRequest();
req.open('POST', '/some/test', false); 
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() {
  console.log('success');
};

req.onerror = function() {
  console.log('error');
};

req.send(JSON.stringify({
  test : 'test'
}));
问题是Sinon不会触发同步请求的onload或onerror回调。问题在于
FakeXMLHttpRequest
的方法
setResponseBody
。您可以找到以下代码:

if (this.async) {
    this.readyStateChange(FakeXMLHttpRequest.DONE);
} else {
    this.readyState = FakeXMLHttpRequest.DONE;
}
在最近的浏览器中,XmlHttpRequest甚至会触发同步请求的回调。因此,应在以下情况下修改此代码:

if (!this.async) {
    this.readyState = FakeXMLHttpRequest.DONE;
}

this.readyStateChange(FakeXMLHttpRequest.DONE);

如果您这样修补sinon.js,一切都会正常运行。

问题来自使用jQuery 2.1的sinon.js:

jQuery 2.1发出如下同步ajax请求:

var req = new XMLHttpRequest();
req.open('POST', '/some/test', false); 
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() {
  console.log('success');
};

req.onerror = function() {
  console.log('error');
};

req.send(JSON.stringify({
  test : 'test'
}));
问题是Sinon不会触发同步请求的onload或onerror回调。问题在于
FakeXMLHttpRequest
的方法
setResponseBody
。您可以找到以下代码:

if (this.async) {
    this.readyStateChange(FakeXMLHttpRequest.DONE);
} else {
    this.readyState = FakeXMLHttpRequest.DONE;
}
在最近的浏览器中,XmlHttpRequest甚至会触发同步请求的回调。因此,应在以下情况下修改此代码:

if (!this.async) {
    this.readyState = FakeXMLHttpRequest.DONE;
}

this.readyStateChange(FakeXMLHttpRequest.DONE);

如果你这样修补sinon.js,一切都会正常。

AJAX是异步的,当你调用控制台日志时,AJAX调用仍在处理中。即使选项中有一个
async:false
,我也没有看到。我不知道,async false是一个糟糕的做法,因此我从未使用过它。我知道这是一个糟糕的做法。但是我有一些。。。“遗留代码”,我无法更改:(即使没有jQuery,我也无法使用Sinon测试同步请求,经过一段时间的改进后,我决定禁用这些测试。如果我没记错的话(已经有一段时间了)Sinon没有为同步请求触发readystatechange事件,也没有在其模拟XMLHttpRequest对象上设置正确的完成状态。AJAX是异步的,当您调用控制台日志时,AJAX调用仍在处理中。即使选项中有一个
async:false
,我也没有看到。我不知道,async false是一个错误糟糕的做法,因此我从未使用过它。我知道这是一个糟糕的做法。但我得到了一些…“遗留代码”,我无法改变它:(即使没有jQuery,我也无法使用Sinon测试同步请求,经过一段时间的研究,我决定禁用这些测试。如果我没有记错(已经有一段时间了)Sinon没有为同步请求触发readystatechange事件,也没有在其模拟XMLHttpRequest对象上设置正确的完成状态。