将错误页面从Angular重定向到Rails并刷新整页

时间:2016-01-22 08:08:07

标签: ruby-on-rails angularjs

我在Rails 4.2.4 RESTful API上有一个Angular 1.4.8应用程序。

app.js

var myApp = angular.module('myApp',
[
    'ngResource',
    'ngRoute',
    'templates',
    'ui.mask',
    'ng-rails-csrf'
]);

myApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider
        .when('/', { controller: 'DashboardController', templateUrl: 'dashboard/index.html' })
        .when('/dashboard', { controller: 'DashboardController', templateUrl: 'dashboard/index.html' })
        .when('/settings/account', { controller: 'SettingsAccountController', templateUrl: 'settings/account.html' })
}]);

myApp.factory('httpResponseInterceptor',['$q','$location',
function($q,$location){
    return {
        response: function(response){
            if (response.status === 401) {
                console.log("Response 401");
            }
            return response || $q.when(response);
        },
        responseError: function(rejection) {
            if (rejection.status === 401) {
                console.log("Response Error 401", rejection);
                $location.path('/401');
            }
                        if (rejection.status === 403) {
                console.log("Response Error 403", rejection);
                $location.path('/403');
            }
                        else if (rejection.status === 404) {
                console.log("Response Error 404", rejection);
                $location.path('/404');
            }
                        else if (rejection.status === 500) {
                console.log("Response Error 500", rejection);
                $location.path('/500');
            }
            return $q.reject(rejection);
        }
    }
}])
.config(['$httpProvider',function($httpProvider) {
    //Http Intercpetor to check auth failures for xhr requests
    $httpProvider.interceptors.push('httpResponseInterceptor');
}]);

如您所见,我已设置应用程序以删除hashbang: $locationProvider.html5Mode(true);

在Rails中,这是我的路由(剥离):

require 'api_constraints'

Rails.application.routes.draw do

  namespace :api, format: :json, defaults: {format: 'json'} do
    scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
      get '/settings/account' => "settings#edit_account", as: :edit_settings_account
      put '/settings/account' => "settings#update_account", as: :update_settings_account
      post '/feedback' => "feedbacks#create", as: :feedback
      get '/services' => "services#list", as: :services
    end
  end

  # Catch errors
  get "/401", :to => "errors#access_denied"
  get "/403", :to => "errors#access_denied"
  get "/404", :to => "errors#not_found"
  get "/422", :to => "errors#unacceptable"
  get "/500", :to => "errors#internal_error"
  get '*path', :to => 'sessions#new'

  root 'dashboard#index'

end

和相对错误控制器:

class ErrorsController < ApplicationController
  skip_authorization_check

  def access_denied
    render :status => 401
  end

  def not_found
    render :status => 404
  end

  def unacceptable
    render :status => 422
  end

  def internal_error
    render :status => 500
  end

end

所以我的问题是当发生异常时,例如我访问了一个页面而用户没有授权这样做,我在控制台中收到响应错误,httpResponseInterceptor将此错误转发到/403/401页面通过Angular,没有显示任何内容。如果我按刷新或直接输入/401地址,我会转到实际模板。

如果刷新页面,则路由是正确的,但如果Angular内发生响应错误并且调用了$ location,则地址栏中的url会发生变化。

解决方案可以是在重定向到/<error_route>页面时刷新/重新加载整个页面。或者当然纠正我在整个结构中犯错的东西。

请指教。

0 个答案:

没有答案