AngularJS + Django:URL刷新或直接访问未正确加载

时间:2015-07-23 11:57:52

标签: javascript angularjs django redirect angular-ui-router

我们在我们的Django应用程序中嵌入了AngularJS,URL路由由AngularJS ui-router处理。所有这些都可以在使用ui-sref并在应用程序中单击的部分之间正常导航。

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'
          }
        }
...

问题是当用户导航到非根页面时(例如http://example.com/dashboard/profile/),用户刷新浏览器,重新加载浏览器的URL或只是粘贴在非根URL中直接进入浏览器。在这种情况下,用户不会在浏览器中加载保留相同URL的页面,而是被重定向到根页面(http://example.com/dashboard/)。

由于路由由Angular处理,因此在服务器端我们没有为这些非根URL定义任何url路由;相反,我们有中间件将404重定向到根页面:

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

我们希望路由器能够维护原始网址并将用户带回原始网页(即“dashboard/profile”)。注意我们在Angular中设置了HTML5Mode,如下所示:

$locationProvider.html5Mode = true;

我们的理解和/或设置存在一些错误,并希望澄清。

1 个答案:

答案 0 :(得分:9)

我们希望路由器能够维护原始网址并将用户带回原始网页。

这就是误解。

以下是事件序列:

  1. 用户在位置栏中输入http://example.com/dashboard/profile/
  2. 浏览器向服务器发送GET请求以获取该URL。
  3. 您的服务器使用301重定向响应进行响应。
  4. 浏览器会看到该回复并向GET发送新的http://example.com/dashboard/请求。
  5. 服务器使用您的Angular页面进行响应。
  6. Angular应用程序启动并查看window.href以查看当前路由是什么。它会看到根路径并做出适当的响应。
  7. 换句话说,当您重定向时,您将丢失原始网址。

    解决方案很简单:只需返回页面以响应任何(有效)URL,而不是重定向。这样就维护了请求的URL,当Angular启动时,它将能够找到正确的路径。 (这假设路由在Angular中正确设置,但听起来你的工作正常。)

    实施也很简单。只需更改你的Django urls.py

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

    这样的事情:

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