webentwicklung-frage-antwort-db.com.de

Wie lässt sich der Router mit dem Statuscode 404 reagieren?

Ich verwende reakter Router als root und alle Anfragen unter "/" werden an den reaktiven Router gerichtet. Wenn der Router festgestellt hat, dass die URL keiner der definierten Komponenten entspricht, wird er mit der NoMatch-Komponente gerendert. Und hier ist das Problem, NoMatch wird gerendert und das ist es, was ich will, aber der Statuscode ist immer noch 200 statt 404. Und wenn meine CSS- oder JS-Dateien mit einer falschen URL-Reaktion abgelegt werden, reagiert der Router genauso, er antwortet mit 200 ! Und dann sagt mir die Seite, dass es Probleme mit dem Inhaltstyp meiner Ressourcen gibt!

Wie kann ich also reaktiver Router verwenden, um alles in "/" zu behandeln und trotzdem 404-Fehler richtig behandeln (mit 404-Statuscode antworten)?

code in reaktem Router

render((
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <IndexRoute component={Index}/>
      <Route path="archived" component={App}>
        <IndexRoute component={ArchivedPage}/>
        <Route path="project/:projectId" component={ArchivedDetailPage}/>
      </Route>
      <Route path="*" component={NoMatch}/>
    </Route>
  </Router>
), document.getElementById('app'));

die serverseite

  router.use('/', function(req, res, next) {
    res.render('index-react', {
      title: 'some title'
    });
  });
11
Liang

Mit dem reakt-router 2.0.0 können Sie Folgendes tun:

<Route path="*" component={NoMatch} status={404}/>

BEARBEITEN:

Sie müssten ein benutzerdefiniertes Attribut für Ihre Routendefinition erstellen, wie Sie oben sehen (Status).

Wenn Sie Ihre Komponente auf Serverseite rendern möchten, überprüfen Sie dieses Attribut und senden Sie eine Antwort mit dem Code dieses Attributs:

routen.js

import React from 'react';
import {IndexRoute, Route} from 'react-router';

import {
    App,
    Home,
    Post,
    NotFound,
} from 'containerComponents';

export default () => {
    return (
    <Route path="/" component={App}>

        <IndexRoute component={Home} />
        <Route path='post/' component={Post} />

        { /* Catch all route */ }
        <Route path="*" component={NotFound} status={404} />

    </Route>
  );
};

server.js:

import { match } from 'react-router';
import getRoutes from './routes';
....
app.use((req, res) => {
match({ history, routes: getRoutes(), location: req.originalUrl }, (error, 
        redirectLocation, renderProps) => {
        if (redirectLocation) {
          res.redirect(redirectLocation.pathname + redirectLocation.search);
        } else if (error) {
          console.error('ROUTER ERROR:', error);
          res.status(500);
        } else if (renderProps) {

            const is404 = renderProps.routes.find(r => r.status === 404) !== undefined;
        }
        if (is404) {
          res.status(404).send('Not found');
        } else {
            //Go on and render the freaking component...
        }
    });
});

Tut mir leid ... sicherlich hat meine Lösung nicht von alleine funktioniert, und ich habe den richtigen Code vermisst, in dem Sie dieses Attribut tatsächlich überprüfen und entsprechend rendern.

Wie Sie sehen, sende ich nur den Text 'Not found' an den Client. Am besten ist es jedoch, wenn Sie die Komponente zum Rendern von renderProps (in diesem Fall NoMatch) fangen und rendern.

Prost

13
rmartrenado

Zen: Wie lautet der Fehlercode eines stillen Netzwerks?

Ich habe auch über diese Frage nachgedacht. Im seltenen Fall ändern Sie den HTTP-Fehlercode nicht. Wir denken, wir sollten es tun, weil eine zufällige URL aufgerufen wurde, aber warum?

In einer SPA (Single Page Application) gibt es keinen Netzwerkverkehr, sondern lediglich das Wechseln der Fenster. Der HTTP-Fehlercode befindet sich in den Kopfzeilen zum Bereitstellen einer neuen Seite, während sich der gesamte Inhalt in einem benannten <div> befindet, der keine neue Seite neu lädt. Man müsste die Seite rausschmeißen, eine neue Seite übertragen und rendern, um den 404-Rückkehrcode zu erhalten, und dann die ursprüngliche Seite erneut senden, wenn sich der Benutzer entfernt.

Und es ist nur der Benutzer. Der 404-Fehlercode oder jeder andere HTTP-Code ist ein Hinweis auf den Browser oder den Dienst. Wenn der Anforderer ein Browser ist, erhält der Mensch eine bessere Anzeige, als der Browser liefern könnte. Wenn der Anforderer ein Crawler ist, sucht er wahrscheinlich nach 404 in <h1>. Wenn der Anforderer Ihre Website als API verwendet, warum ist das eine gute Sache?

Die Antwort ist also, dass wir die HTTP-Statuscodes aus Gewohnheit setzen. Nicht.

6
Charles Merriam

Dazu müssen Sie das Spiel auch auf dem Server ausführen, um zu sehen, ob eine Route passt. Wenn Sie dies tun, können Sie natürlich auch ein volles serverseitiges Rendering durchführen! Lesen Sie die Anleitung zum Rendern von Servern .

3
taion

Ich habe ein bisschen gegraben, so machen wir Dinge in der v4-Version.

<Route
  render={({ staticContext }) => {
    if (staticContext) {
      staticContext.statusCode = 404
    }
    return <NotFound />
  }}
/>

Die Route-Komponente wird für den Zugriff auf die staticContext-Komponente verwendet, die über eine statusCode-Eigenschaft verfügt, die Sie festlegen können, wenn Sie die StaticRouter-Komponente für die Wiedergabe auf dem Server verwenden.

Server-Code sieht ungefähr so ​​aus (mit etwas TypeScript-Typisierung)

const currentLocation: Location = {
  pathname: req.pathname,
  search: req.search,
  hash: '',
  state: undefined
}

const staticRouterContext: StaticContext & StaticRouterContext = {}

ReactDOMServer.renderToString(
  <StaticRouter location={currentLocation} context={staticRouterContext}>
  ...
  </StaticRouter>
)

if (staticRouterContext.statusCode) {
  res.status(staticRouterContext.statusCode)
}

Anmerkung: Ich denke, die Typisierung ist etwas unkonventionell, da die Variable StaticRouterContext nicht über die statusCode-Eigenschaft aus der StaticContext-Schnittstelle verfügt. Wahrscheinlich ein Fehler bei den Typisierungen. Das funktioniert aber gut.

1
John Leidegren