$location /在html5和hashbang模式之间切换/链接重写



我的印象是Angular会重写模板中锚标签的href属性中的url,这样它们就可以在html5模式或hashbang模式下工作。位置服务的文档似乎说HTML链接重写会处理散列的情况。因此,我希望当不在HTML5模式下时,将插入哈希值,而在HTML5模式下,它们不会。

然而,似乎没有重写发生。下面的示例不允许我只更改模式。应用程序中的所有链接都需要手工重写(或在运行时从变量派生)。我是否需要根据模式手动重写所有url ?

在Angular 1.0.6、1.1.4或1.1.3中,我没有看到任何客户端url重写。似乎所有的href值都需要在hashbang模式前加上#/,在html5模式前加上/。

是否需要一些配置来导致重写?我是不是看错了医生?做其他傻事?

下面是一个小例子:

<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.3/angular.js"></script>
</head>
<body>
<div ng-view></div>
<script>
angular.module('sample', [])
.config(
['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
//commenting out this line (switching to hashbang mode) breaks the app
//-- unless # is added to the templates
$locationProvider.html5Mode(true);
$routeProvider.when('/', {
template: 'this is home. go to <a href="/about"/>about</a>'
});
$routeProvider.when('/about', {
template: 'this is about. go to <a href="/"/>home</a'
});
}
])
.run();
</script>
</body>

附录:在重读我的问题时,我发现我使用了"重写"一词,但没有清楚地说明我想在谁和什么时候进行重写。这个问题是关于如何获得Angular如何在渲染路径时重写url,以及如何让它跨两种模式统一地解释JS代码中的路径。它是而不是关于如何让web服务器重写兼容html5的请求。

文档对AngularJS的路由并不是很清楚。它谈到了Hashbang和HTML5模式。实际上,AngularJS的路由有三种模式:

<<ul>
  • Hashbang模式/gh>HTML5模式
  • Hashbang在HTML5模式
  • 每种模式都有一个各自的LocationUrl类(LocationHashbangUrl, LocationUrl和LocationHashbangInHTML5Url)。

    为了模拟URL重写,你必须将html5mode设置为true,并按照如下方式修饰$sniffer类:

    $provide.decorator('$sniffer', function($delegate) {
    $delegate.history = false;
    return $delegate;
    });
    

    我现在将更详细地解释:

    <标题>

    Hashbang模式配置:

    $routeProvider
    .when('/path', {
    templateUrl: 'path.html',
    });
    $locationProvider
    .html5Mode(false)
    .hashPrefix('!');
    

    当您需要在HTML文件中使用带有散列的url时,例如

    <a href="index.html#!/path">link</a>
    

    在浏览器中,您必须使用以下链接:http://www.example.com/base/index.html#!/base/path

    可以看到,在纯Hashbang模式下,HTML文件中的所有链接都必须以"index.html#!"这样的基开头。

    <标题>

    HTML5模式配置:

    $routeProvider
    .when('/path', {
    templateUrl: 'path.html',
    });
    $locationProvider
    .html5Mode(true);
    

    你应该在HTML-file

    中设置基
    <html>
    <head>
    <base href="/">
    </head>
    </html>
    

    在这种模式下,你可以在HTML文件中使用没有#的链接

    <a href="/path">link</a>
    

    浏览器链接:

    http://www.example.com/base/path
    

    HTML5模式下的Hashbang

    当我们实际使用HTML5模式,但在一个不兼容的浏览器中,此模式被激活。我们可以通过修饰$sniffer服务并将历史记录设置为false来在兼容的浏览器中模拟此模式。

    配置:

    $provide.decorator('$sniffer', function($delegate) {
    $delegate.history = false;
    return $delegate;
    });
    $routeProvider
    .when('/path', {
    templateUrl: 'path.html',
    });
    $locationProvider
    .html5Mode(true)
    .hashPrefix('!');
    

    设置基础在HTML-file:

    <html>
    <head>
    <base href="/">
    </head>
    </html>
    

    在这种情况下,链接也可以在HTML文件

    中不使用哈希值。
    <a href="/path">link</a>
    

    浏览器链接:

    http://www.example.com/index.html#!/base/path
    

    对于未来的读者,如果你正在使用Angular 1.6,您还需要更改hashPrefix:

    appModule.config(['$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('');
    }]);
    

    不要忘记在你的HTML设置基础<head>:

    <head>
    <base href="/">
    ...
    </head>
    

    关于变更日志的更多信息在这里.

    这花了我一段时间来弄清楚,所以这就是我是如何让它工作的- Angular WebAPI ASP Routing没有# for SEO

    1. add to Index.html - base href="/">
    2. 添加locationProvider.html5Mode美元(真正的);app.config

    3. 我需要一个特定的控制器(在home控制器中)在上传图像时被忽略,所以我将该规则添加到routecconfig

      routes.MapRoute(
      name: "Default2",
      url: "Home/{*.}",
      defaults: new { controller = "Home", action = "SaveImage" }
      );
      
    4. 在全球。请添加以下内容-确保忽略API和图像上传路径,让它们正常运行,否则将重新路由其他所有内容。

      private const string ROOT_DOCUMENT = "/Index.html";
      protected void Application_BeginRequest(Object sender, EventArgs e)
      {
      var path = Request.Url.AbsolutePath;
      var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase);
      var isImageUpload = path.StartsWith("/home", StringComparison.InvariantCultureIgnoreCase);
      if (isApi || isImageUpload)
      return;
      string url = Request.Url.LocalPath;
      if (!System.IO.File.Exists(Context.Server.MapPath(url)))
      Context.RewritePath(ROOT_DOCUMENT);
      }
      
    5. 确保使用$location.url('/XXX')而不是window。位置……重定向

    6. 使用绝对路径引用CSS文件

    <link href="app/content/bootstrapwc.css" rel="stylesheet" />
    

    最后注意-这样做给了我完全的控制,我不需要对web配置做任何事情。

    希望这对我有帮助,因为我花了一段时间才弄明白。

    我希望能够使用HTML5模式和固定令牌访问我的应用程序,然后切换到hashbang方法(保留令牌,以便用户可以刷新他的页面)。

    访问我的应用的URL:

    http://myapp.com/amazing_url?token=super_token

    当用户加载页面时:

    http://myapp.com/amazing_url?token=super_token#/amazing_url

    当用户导航时:

    http://myapp.com/amazing_url?token=super_token#/another_url

    这样,我将令牌保留在URL中,并保留用户浏览时的状态。我失去了一点URL的可见性,但没有完美的方法来做到这一点。

    所以不要启用HTML5模式然后添加这个控制器:

    .config ($stateProvider)->
    $stateProvider.state('home-loading', {
    url: '/',
    controller: 'homeController'
    })
    .controller 'homeController', ($state, $location)->
    if window.location.pathname != '/'
    $location.url(window.location.pathname+window.location.search).replace()
    else
    $state.go('home', {}, { location: 'replace' })