【问题标题】:Angularjs: How to intercept errors in external url $resource or $http service?Angularjs:如何拦截外部 url $resource 或 $http 服务中的错误?
【发布时间】:2014-06-30 23:43:54
【问题描述】:

我在与我的 grunt 服务器不同的服务器上提供了一项服务,该服务器为我的 angularjs 应用程序提供服务。
外部服务器是 Apache 服务器,使用 PHP 提供 JSON 数据。 我想拦截任何可能的服务器错误(从“服务器停机”到“404”...)。

我尝试过这样使用拦截器:

app.factory('myFactory', function($resource) {
  return $resource('http://www.remote.server.com/api/WRONGPATH',
});

app.config(function ($routeProvider, $httpProvider) {

  ...

  $httpProvider.responseInterceptors.push(function($q) {
    return function(promise) {
      return promise.then(function(successResponse) {
        if (successResponse.config.method.toUpperCase() !== 'GET') {
          console.info('success');
        }
        return successResponse;
      }, function(errorResponse) {
        switch (errorResponse.status) {
          case 401:
            console.info('wrong usename or password');
            break;
          case 403:
            console.info('no rights to do this');
            break;
          case 500:
            console.info('server internal error: ' + errorResponse.data);
            break;
          default:
            console.info('error ' + errorResponse.status + ': ' + errorResponse.data);
        }
        return $q.reject(errorResponse);
      });
    };
  });

});

没有成功:我总是陷入“默认”开关情况,errorResponse.status == 0
我想这是因为浏览器在拦截 CORS 错误时停止...
如果我用本地网址更改远程网址,一切都会正常...

是否有可能处理 angular.js $resource(或 $http)远程请求错误?

我也会接受设计转变建议,比如以类似 grunt 的方式重新实现我的 PHP 服务......(我的 PHP 服务 - 实际上 - 只是从服务器文件夹打印图像名称的 JSON 列表...... .).

【问题讨论】:

    标签: javascript angularjs cors


    【解决方案1】:

    我相信您将拦截器推到了错误的位置。 $http docs 表示您应该继续前进:

    $httpProvider.interceptors
    

    而不是:

    // I can only find references to this on old tutorials, so maybe it's been deprecated
    $httpProvider.responseInterceptors 
    

    所以你会有类似的东西:

    $httpProvider.interceptors.push(function($q) {
      return {
        'response': function(response) {
          if (successResponse.config.method.toUpperCase() !== 'GET') {
            console.info('success');
          }
          return response || $q.when(response);
        },
        'responseError': function(response) {
           switch (response.status) {
            case 401:
              console.info('wrong usename or password');
              break;
            case 403:
              console.info('no rights to do this');
              break;
            case 500:
              console.info('server internal error: ' + response.data);
              break;
            default:
              console.info('error ' + response.status + ': ' + response.data);
          }
    
          return $q.reject(response);
        }
      };
    });
    

    工作 plnkr:here

    【讨论】:

    • 谢谢,但这种方式唯一的区别是我拦截了 所有 响应,甚至是好的(200 条)响应,而不仅仅是 error 响应...但是,即使添加 404 案例,它也不会拦截 404 错误...
    • 好吧,使用上面的 responseInterceptors 也会拦截 all 响应。我只是建议您使用 angular 建议的格式。您可以使用现有的 switch 语句过滤它们。你能把plnkr 放在一起吗?
    • 我已经使用您的原始代码制作了一个 plnkr,它可以正常工作:plnkr.co/edit/y42BOA0Q3Pi1GzCX3JPU
    • 谢谢!是否可以将其扩展到 $resource,而不是 ng-click ?
    • 拦截器适用于所有基于 http 的操作,这就是为什么这在我的示例 plnkr 中有效。不绑定 ng-click,ng-click 只是用来调用控制器作用域上的一个方法,然后使用工厂创建的资源。
    【解决方案2】:

    据我了解,这是一个与 CSRF/XSRF 保护有关的问题,而不是 AngularJS。您将在其他框架或 poj 中遇到相同的问题。在 PHP 中,如果您跨域访问内容,则需要启用 CORS,并且需要指定需要访问或打开它的服务器。

    http://www.w3.org/wiki/CORS_Enabled http://enable-cors.org/server_php.html

    本质上,AngularJS 受限于浏览器提供的响应,这反过来又限制了响应,因为由于 XSRF 保护,请求是未经授权的。另外,对于 AngularJS 和 XSRF,它会读取令牌会话 cookie(由服务器提供)并将其放入后续请求的 HTTP 标头中,然后由服务器决定是否接受它。

    https://docs.angularjs.org/api/ng/service/$http

    【讨论】:

    • 谢谢。我确实在我的 PHP 页面中启用了 CORS 访问(<?php header("Access-Control-Allow-Origin: *"); ?> ...),但问题是我想拦截服务器关闭或 404 之类的错误,这当然甚至不涉及脚本代码...
    猜你喜欢
    • 1970-01-01
    • 2014-06-07
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多