How do I throw a real 404 or 301 with an Angular pushstate URL

superluminary picture superluminary · Jan 6, 2015 · Viewed 8.6k times · Source

I'm using $routeProvider and $locationProvider to handle pushstate URLS in a single page app (SPA), something like this:

angular.module('pets', [])

  .config(function($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);
    $routeProvider.when('/pet/:petId', {
      controller: 'petController'
    });
  })

  .controller('petController', function($scope, petService, $routeParams){
    petService.get('/api/pets/' + $routeParams.petId).success(function(data) {
      $scope.pet = data;
    });
  });

The URL is used to pull content from the server which may or may not exist.

If this was an ordinary multipage website, a request for missing content would trigger a 404 header response from the server, and a request for moved content would trigger a 301. This would alert Google to the missing or moved content.

Say for example I hit a URL like this:

http://example.com/pet/123456

and say there is no such pet in the database, how can my SPA return a 404 on that content.

Failing this, is there some other way to correctly alert the user or search engine that the requested URL doesn't exist? Is there some other solution I'm not considering?

Answer

a better oliver picture a better oliver · Jan 9, 2015

The real question is does http://example.com/pet/123456 return anything at all?

If your starting point is http://example.com/ and there's a link to http://example.com/pet/123456 then Angular will call the petController which in turn makes an AJAX call to http://example.com/api/pet/123456.

A crawler wouldn't do that but instead would try to call http://example.com/pet/123456 directly.

So your server must be able to handle that call. If there is no pet with the id 123456 then it should return 404. Problem solved. If there is then it should return the SPA. The application should then handle the situation accordingly.