AngularJS + Django: actualisation d'URL ou accès direct ne pas correctement chargé

Nous avons intégré AngularJS dans notre application Django, avec un routage d'URL géré par AngularJS ui-router . Tout fonctionne bien, naviguer entre les partiels en utilisant ui-sref et cliquer autour de l'application.

return $stateProvider.state('root.dashboard', { abstract: true, url: 'dashboard/' }).state('root.dashboard.profile', { url: 'profile/', views: { '@': { templateUrl: Urls['dashboard:profile'](), controller: 'ProfileController' } } }).state('root.dashboard.home', { url: '', views: { '@': { templateUrl: Urls['dashboard:dashboard_home'](), controller: 'DashboardController' } } ... 

Le problème est lorsque l'utilisateur a navigué vers une page non-racine (par exemple, http://example.com/dashboard/profile/ ), et l'utilisateur actualise le navigateur, recharge l'URL du navigateur ou simplement les pâtes dans le URL non racine directement dans le navigateur. Au lieu de charger la page contenant la même URL dans le navigateur, l'utilisateur est redirigé vers la page racine ( http://example.com/dashboard/ ) dans ce cas.

Étant donné que le routage est traité par Angular, du côté du serveur, nous n'avons aucune route url définie pour ces URL non root; Au lieu de cela, nous avons un middleware qui redirige 404 vers la page racine:

 class Redirect404(object): def process_response(self, request, response): if response.status_code != 404 or request.method != 'GET': return response return HttpResponsePermanentRedirect('/dashboard') 

Nous nous attendons à ce que le routeur soit en mesure de conserver l'URL d'origine et de ramener l'utilisateur sur la page d'origine (c.-à-d. ' dashboard/profile de dashboard/profile '). Notez que nous avons défini HTML5Mode en angulaire comme suit:

 $locationProvider.html5Mode = true; 

Il y a une erreur dans notre compréhension et / ou configuration, et nous aimerions obtenir des éclaircissements.

Nous nous attendons à ce que le routeur puisse maintenir l'URL d'origine et ramener l'utilisateur sur la page d'origine.

C'est le malentendu.

Voici la séquence des événements:

  1. L'utilisateur tape http://example.com/dashboard/profile/ dans la barre de localisation.
  2. Le navigateur envoie une requête GET au serveur pour cette URL.
  3. Votre serveur répond avec une réponse de redirection 301 .
  4. Le navigateur voit cette réponse et envoie une nouvelle requête GET à http://example.com/dashboard/ .
  5. Le serveur répond avec votre page angulaire.
  6. L'application Angular démarre et regarde window.href pour voir quelle est l'itinéraire actuel. Il voit l'itinéraire racine et répond de manière appropriée.

En d'autres termes, lorsque vous redirigez, vous perdez l'URL d'origine.

La solution est simple: au lieu de rediriger, renvoyez simplement votre page en réponse à n'importe quelle URL (valide). De cette façon, l'URL demandée est maintenue, et lorsque Angular démarre, elle pourra trouver le bon itinéraire. (Cela suppose que le routage est correctement configuré dans Angular, mais il semble que vous travaillez.)

La mise en œuvre est également simple. Changez votre Django urls.py de quelque chose comme ceci:

 urlpatterns = [ url(r'^dashboard/$', my_view), ] 

À quelque chose comme ça:

 urlpatterns = [ url(r'^dashboard/.*$', my_view), ]