9

我在单独的 .js 文件中为前端后端环境编写了这个小代码。myfile.json每当有 ajax 调用时,我都需要获取/somelink

angular.module('myApp')
.config(function($provide) {
  $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
})
.run(function($httpBackend, $http) {

  $httpBackend.whenGET('/somelink').respond(function(method, url, data) {
    $http({method: 'GET', url: '/somelink/myfile.json'})
    .success(function(data, status, headers, config) {
      return data;
    })
    .error(function(data, status, headers, config) {
    });

  });
});

但是这段代码不起作用并给了我错误:

Error: Unexpected request: GET /somelink/myfile.json

有人可以帮我解决这个问题吗?

请注意,我不想直接调用 $http 在我的代码中获取 .json 文件,因为这会破坏生产代码。这样做的目的是单独保留此代码以进行后端开发。

谢谢。

更新 1:

我补充说:

$rootScope.$apply(); 
$httpBackend.flush();

现在,除了以前的相同错误之外,我还有另一个错误:Uncaught Error: No pending request to flush !

更新 2:

玩了一圈之后,我发现了一个小技巧。我把它放在.run()所有其他 $httpBackend 模拟之前。此外,此.js文件必须放在所有控制器/服务/指令之前和 app.js 引导程序之后。

  var data;

  $.ajax({
    type: 'GET',
    async: false,
    url: '/somelink/myfile.json'
  }).success(function(res) {
    data = res;
  }).error(function(data) {
  });

然后这个:

$httpBackend.whenGET('/somelink').respond(data);

关键是async: false这样可以确保将 JSON 加载到 variabledata中。所有这些都必须在其他对象触发并调用 ajax 事件之前发生。这仅适用于前端后端开发。生产时,当然会删除这个 .js 文件。我不太喜欢这个是因为使用async: false和直接$.ajax()而不是$http

4

5 回答 5

8

以下为我工作,没有任何黑客

$httpBackend.whenGET('/endpoint').respond($resource("/path/to.json").query());

礼貌https://groups.google.com/d/msg/angular/grbwk-VehDE/UBIho6qcmLMJ

于 2014-06-18T07:21:52.983 回答
4

这个问题的一个非常干净的解决方案是使用,plain vanilla JavaScript因为$httpBackend它不是用来处理asynchronous请求的。

此方法不需要jQuery代码。

$httpBackend.when('GET', 'http://localhost:3000/api/data').respond(getData());

function getData() {
               var request = new XMLHttpRequest();
               request.open('GET', '/db/myData.json', false);
               request.send(null);

               return [request.status, request.response, {}];
}

我从以下位置得到这个提示: https ://stackoverflow.com/a/24287558/4742733

于 2015-11-29T09:55:02.193 回答
3

我知道这是一个迟到的回应,但会分享我的经验,希望对未来的同行有所帮助。

多亏了这篇非常有用的博客文章,我成功地实现了一个可工作的模拟后端。

首先,我将所有端点作为常量放在一个地方,以便只定义一次并让它们在模拟后端、我的测试中以及显然在所有负责 AJAX 调用的服务中可用。

angular.module('appName.urls', [])
 .constant('API_endpoints', {
   login: 'authentication/login',
   logout: 'authentication/logout',
   signUp: 'authentication/signup',
   userList: 'users/list'
 });

然后我将其添加ngMockE2E为整个应用程序的依赖项。

angular.module('appName', [
  'ui.router',
   ... 
  'ngMockE2E'
])

然后我为实际模拟的后端创建了一个文件,让我们调用它fakeBackend.js并在index.html. 该文件取自上面的链接,但这是我实现的简化示例(此处提供模拟登录):

angular.module('appName').run(function($httpBackend, API_endpoints) {

   var credentials = {
    email : 'a@a.a',
    password : '12345'
  };

  $httpBackend.whenPOST(API_endpoints.login)
              .respond(function(method, url, data) {

    var req = JSON.parse(data),
        res;
    // very light credential check...
    if(req.email === credentials.email && req.password === credentials.password ){
        // generate a successful response
        res = [200, {uuid:1}, {}];
    } else {
        // generate an error if credentials are wrong
        res = [400, {}, {}];
    }
    return res;
  });

   // Respond to all templates request
   // Every file in states/ folder will be served automatically
   $httpBackend.whenGET(/states\//).passThrough();
}):

还要注意最后一行,它提供了我states所有模板所在的文件夹中的所有内容。这显然是一个非常简单的例子,但是博文作者也分享了一个非常详细和有用的plunkr

于 2015-02-13T23:19:55.510 回答
2

我(和许多其他人)在使用 $httpBackend 进行测试时遇到了这个问题。我还没有将它用于后端开发。测试中的解决方案是:

AngularJS 固执己见且饥肠辘辘,因此要在测试中触发 $http 请求,您必须使用 $apply 或 $digest。

为了使 $http 在我的测试中工作,我必须

root.$apply(); 
httpBackend.flush();

也许这样的事情会帮助你。

于 2014-01-04T01:00:15.940 回答
1

@Aakash Shah 使用原始 javascript 发出同步 xhr 请求的答案对我来说效果惊人。这里有更多代码来阐明我是如何概括它的。

addMock('/mocks/json/myjson.json', new RegExp('yada/.*/getMyJson'));

    function addMock(jsonFilePath, urlToReplace) {
        $httpBackend.whenGET(urlToReplace)
            .respond.apply(this, getData(jsonFilePath)); // apply to put the parameters as args
    }

    function getData(jsonFilePath) {
        var request = new XMLHttpRequest();
        request.open('GET', jsonFilePath, false);
        request.send(null);

        return [request.status, request.response, {}];
    }
于 2015-11-30T17:27:57.673 回答