问题
I am using ui.router & ngResource with AngularJS, & my question is :
How do I RENDER 404 without redirecting to it e.g A user typed http://www.example.com/wrong-page-name , he should just be shown the 404 page, and the URL shouldn't change.
Currently this is how I did it but it redirects
angular.module('app')
.run(['$rootScope', '$state', function($rootScope, $state) {
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
if(error.status === 404) {
$state.go('innerPages.page', {slug:"not-found"});
}
});
})
.config(['$stateProvider','$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider.state('innerPages.page', {
url: ':slug',
views : {
'content@':{
templateUrl : '...',
controller : 'pageController'
},
'pageHeader@' : {
templateUrl : "...",
controller : 'pageController'
}
},
resolve:{
page: ['pageService', '$stateParams', function (pageService, $stateParams) {
return pageService.get({slug:$stateParams.slug}).$promise;
}]
}
});
}]);
Thanks for Help !
回答1:
Why don't you just show the 404 template?
<any ng-view ng-class="{'hidden': notFound}"></any>
<div class="not-found-template hidden" ng-class="{'hidden': !notFound}">
<h2>Not Found!</h2>
</div>
And for the css:
.hidden
{
display: none !important;
}
And add a service for error handling (optional)
angular.module('app').service('Errors', function ($rootScope) {
this.handle = function (error, status) {
// not found
switch (status) {
case 404:
alert('Sorry! the page was not found.');
// This is the required line for showing 404 template
$rootScope.notFound = true;
break;
case 500:
alert('Sorry! Error connecting to server.');
break;
case 403:
$location.path('/login');
break;
default:
alert('Sorry! Error connecting to server.');
}
}
});
回答2:
I like to add a recommended and more structured answer:
The $httpInterceptor
factory documented here (see Interceptors paragraph) is used:
For purposes of global error handling, authentication, or any kind of synchronous or asynchronous pre-processing of request or postprocessing of responses
in all of HTTP requests through your app.
Change the responseError method like:
'responseError': function (error) {
//hide any showing loader spinners
loader.hide();
// handle errors by type
var status = error.status;
switch (status) {
// here you can show 404 templates and go more further
case 404:
$rootScope.flags.errorCode = 404;
break;
// here I check if error has messages or it's an internal server error
case 500:
try {
if (!error.data.success && typeof error.data.data.message != 'undefined') {
Notification.error(error.data.message);
} else {
$rootScope.flags.errorCode = 500;
}
} catch (e) {
$rootScope.flags.errorCode = 500;
}
break;
// authenticating for actions that un-authenticated uses can not do, like staring or commenting
case 401:
Popup.show('login');
break;
// showing notification for any other error types
default:
Notification.error('Sorry! Error connecting to server.');
}
return $q.reject(error);
}
about the above code:
Loader
is my custom service to show loader-spinner and may haveoverlay
,onElement
and any other required types.Notification
is also a custom service for notifying client about the result of requests.- Any error templates may be controlled using
flags
object pinned to$rootScope
.
来源:https://stackoverflow.com/questions/28171486/render-404-page-without-redirecting-in-angular-js