16

I $ routeProvider und $ locationProvider bin mit pushstate URLS auf einer einzigen Seite app (SPA) zu handhaben, so etwas wie:Wie kann ich einen echten 404 oder 301 mit einer Winkelpushstate URL werfen

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; 
    }); 
    }); 

Die URL wird verwendet, um Inhalte vom Server abzurufen, die möglicherweise nicht vorhanden sind.

Wenn dies eine normale mehrseitige Website war, würde eine Anforderung für fehlenden Inhalt eine 404-Headerantwort vom Server auslösen und eine Anforderung für verschobenen Inhalt würde eine 301 auslösen. Dies würde Google auf den fehlenden oder verschobenen Inhalt hinweisen.

Sagen Sie zum Beispiel traf ich eine URL wie folgt aus:

http://example.com/pet/123456

und sagen, dass es in der Datenbank, wie kann mein SPA eine 404 auf, dass der Inhalt nicht so Haustier.

Fehlt dies, gibt es eine andere Möglichkeit, den Benutzer oder die Suchmaschine korrekt zu warnen, dass die angeforderte URL nicht existiert? Gibt es eine andere Lösung, die ich nicht in Betracht ziehe?

+0

Wenn der Server einen Statuscode außerhalb des Bereichs 200 zurückgibt, sollte der Aufruf "get" zurückweisen und an den Fehler "callback" übergeben werden: '.success (cb) .error (cb)'. Ist das wonach Sie suchen? –

+0

@DavinTryon - nicht wirklich, ich kann die 404 von der AJAX Anfrage kein Problem, die Frage ist, was damit zu tun ist. In einer mehrseitigen App würde ich einen 404-Statuscode im Antwortheader zurückgeben. Natürlich kann ich das in einem SPA nicht machen. Für einen Benutzer kann ich einfach einen schönen 404 Text rendern, aber wie warne ich einen Crawler, dass die Seite nicht da ist. – superluminary

+0

Ich denke, die Frage könnte dann auf jeden AJAX-Anruf erweitert werden? Mit anderen Worten, wie wird einem Crawler angezeigt, dass ein AJAX-Aufruf (der den zu rendernden Inhalt zurückgibt) einen 404 zurückgibt? –

Antwort

4

Die eigentliche Frage ist nicht http://example.com/pet/123456 Rückkehr haupt etwas?

Wenn Ihr Ausgangspunkt ist http://example.com/ und es gibt einen Link zu http://example.com/pet/123456 dann Angular die petController was wiederum macht einen AJAX-Aufruf zu http://example.com/api/pet/123456 nennen.

Ein Crawler würde das nicht tun, sondern stattdessen versuchen, http://example.com/pet/123456 direkt aufzurufen.

Ihr Server muss also diesen Aufruf verarbeiten können. Wenn es kein Haustier mit der ID 123456 gibt, sollte es 404 zurückgeben. Problem gelöst. Wenn es da ist sollte es das SPA zurückgeben. Die Anwendung sollte dann die Situation entsprechend behandeln.

+1

Das funktioniert gut, wenn man die URL direkt trifft, aber wenn man es per Pushstate trifft, wird nur der API-Aufruf durchgeführt. Der SPA ist bereits geladen. – superluminary

+0

Ah, nein, du hast Recht. Der Crawler trifft die URL direkt. Es liegt dann an dem Server, den SPA oder einen 404-Header zurückzugeben. – superluminary

+1

Endlich eine richtige und korrekte Antwort! Ich würde nur hinzufügen, dass, wenn z.B. Sie haben eine Architektur, bei der das Front-End von einem anderen Server als der API bedient wird. Es ist nicht so einfach herauszufinden, wann 404 zurückgegeben werden soll. Offensichtlich kann Angular das nicht, da es in einem Browser funktioniert. Somit haben Sie 3 Möglichkeiten: 1. Stellen Sie sicher, dass Sie überhaupt keine 404 haben. 2. Ignorieren Sie sie und leiten Sie den Benutzer z. Vorderseite 3. Verwenden Sie einen Weg, um Ihre Seiten prerender (z. B. prerender.io hat einen geeigneten Mechanismus für 404s: https://prerender.io/documentation/best-practices). Bemerkenswert ist, dass nur die dritte Option SEO-freundlich ist. –

0

Versuchen Sie, diese

angular.module('pets', []) 
 

 
    .config(function($routeProvider, $locationProvider) { 
 
    $locationProvider.html5Mode(true); 
 
    $routeProvider.when('/pet/:petId', { 
 
     controller: 'petController' 
 
    }). otherwise({ yourUrl:'/404.html'}) // Render 404 view; 
 
    })

+0

Schön, aber was, wenn http://api.example.com/pets/123456 keine Ressource zurückgibt? – superluminary

+0

Ich glaube wirklich nicht, dass das funktionieren wird. Der Router stimmt mit dem ersten Muster überein, unabhängig davon, ob der spätere Ajax-Aufruf erfolgreich ist. Der Ajax Callback wird ausgeführt, lange nachdem der Router fertig ist. – superluminary

+0

Der einzig denkbare Mechanismus wäre hier eine synchrone Anfrage im Router. – superluminary

3

Gemäß dieser Antwort How do search engines deal with AngularJS applications? sollten Sie Headless Browser verwenden, um Crawler-Anforderungen zu verarbeiten und Snapshots der Seite mit dem entsprechenden Antwortcode zurückzuschicken. https://developers.google.com/webmasters/ajax-crawling/docs/html-snapshot

Das Google-Beispiel enthielt 301,302 oder 404 Fälle nicht. Ihr Code könnte jedoch geändert werden, um den Inhalt des Snapshots zu analysieren und den Antwortcode zu ändern.

Ich fand prerender.io bietet diesen Service, aber es ist nicht kostenlos. Sie haben jedoch einen kostenlosen Plan, wenn Sie weniger als 250 Seiten haben. Prerender fragt, dass Sie im Fall von 404 oder 301 dem DOM ein Meta-Tag hinzufügen.

Dieses Meta-Tag wird dann von ihrem kopflosen Browser erkannt und der Antwortcode geändert.

+1

Diese Information wurde offiziell von Google als veraltet eingestuft. Ihre Crawler können Seiten crawlen, ohne eine Headless-Browserlösung verwenden zu müssen. – Failpunk

+0

@Failpunk danke! das ist sicherlich eine gute Nachricht für SinglePage-Websites da draußen :) –

+0

@Failpunk: Entfernen der Pre-Render-Unterstützung für Ihre Website wäre ein Fehler, da es mehr Bots abgesehen von Google selbst gibt. – diosney

Verwandte Themen