226

我正在学习 AngularJS,但有一件事让我很恼火。

我用来$routeProvider为我的应用程序声明路由规则:

$routeProvider.when('/test', {
  controller: TestCtrl,
  templateUrl: 'views/test.html'
})
.otherwise({ redirectTo: '/test' });

但是当我在浏览器中导航到我的应用程序时,我看到app/#/test的不是app/test.

所以我的问题是为什么 AngularJS 会将此哈希添加#到 url?有没有可能避免它?

4

10 回答 10

268

事实上,对于非 HTML5 浏览器,您需要 #(井号标签)。

否则,他们只会在提到的 href 处对服务器进行 HTTP 调用。# 是一个旧的浏览器短路,它不会触发请求,它允许许多 js 框架在此之上构建自己的客户端重新路由。

如果可用,您可以使用$locationProvider.html5Mode(true)告诉 Angular 使用 HTML5 策略。

这里是支持 HTML5 策略的浏览器列表:http: //caniuse.com/#feat=history

于 2013-01-14T14:36:01.890 回答
47

如果您像其他人所说的那样启用了 html5mode,并创建一个.htaccess包含以下内容的文件(根据您的需要进行调整):

RewriteEngine   On
RewriteBase     /
RewriteCond     %{REQUEST_URI} !^(/index\.php|/img|/js|/css|/robots\.txt|/favicon\.ico)
RewriteCond     %{REQUEST_FILENAME} !-f
RewriteCond     %{REQUEST_FILENAME} !-d
RewriteRule     ./index.html [L]

当用户输入正确的路线时,他们将被引导到您的应用程序,您的应用程序将读取该路线并将他们带到其中的正确“页面”。

编辑:只要确保没有任何文件或目录名称与您的路线冲突。

于 2013-07-28T15:21:53.313 回答
39

让我们写一个看起来简单而简短的答案

在最后的路由器中添加html5Mode(true) ;

app.config(function($routeProvider,$locationProvider) {

    $routeProvider.when('/home', {
        templateUrl:'/html/home.html'
    });

    $locationProvider.html5Mode(true);
})

在 html 头部添加基本标签

<html>
<head>
    <meta charset="utf-8">    
    <base href="/">
</head>

感谢@plus - 详细说明上述答案

于 2015-09-05T15:50:26.260 回答
30

尝试

$locationProvider.html5Mode(true)

更多信息在 $locationProvider
使用 $location

于 2013-01-14T14:29:41.047 回答
12

以下信息来自:
https ://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag

在 Angular 中获取干净的 URL 并从 URL 中删除主题标签非常容易。
默认情况下,AngularJS 将路由带有标签的 URL 例如:

有 2 件事需要做。

  • 配置 $locationProvider

  • 为相对链接设置我们的基础

  • $位置服务

在 Angular 中,$location 服务解析地址栏中的 URL 并对您的应用程序进行更改,反之亦然。

我强烈建议您阅读官方 Angular $location 文档,以了解定位服务及其提供的内容。

https://docs.angularjs.org/api/ng/service/$location

$locationProvider 和 html5Mode

  • 我们将使用 $locationProvider 模块并将 html5Mode 设置为 true。
  • 我们将在定义您的 Angular 应用程序和配置您的路由时执行此操作。

    angular.module('noHash', [])
    
    .config(function($routeProvider, $locationProvider) {
    
       $routeProvider
           .when('/', {
               templateUrl : 'partials/home.html',
               controller : mainController
           })
           .when('/about', {
               templateUrl : 'partials/about.html',
               controller : mainController
           })
           .when('/contact', {
               templateUrl : 'partials/contact.html',
               controller : mainController
           });
    
       // use the HTML5 History API
       $locationProvider.html5Mode(true); });
    

什么是 HTML5 历史 API?这是一种使用脚本来操作浏览器历史记录的标准化方法。这让 Angular 可以在不刷新页面的情况下更改页面的路由和 URL。有关这方面的更多信息,这里有一篇很好的 HTML5 History API 文章:

http://diveintohtml5.info/history.html

相对链接设置

  • 要使用相对链接链接您的应用程序,您需要<base><head>文档中设置。这可能在 Angular 应用程序的根 index.html 文件中。找到该<base>标签,并将其设置为您希望应用的根 URL。

例如:<base href="/">

  • 还有很多其他方法可以配置它,设置为 true 的 HTML5 模式应该会自动解析相对链接。如果您的应用程序的根与 url 不同(例如 /my-base,则使用它作为您的基础。

旧浏览器的回退

  • 对于不支持 HTML5 History API 的浏览器,$location 服务将自动回退到 hashbang 方法。
  • 这对您来说是透明的,您无需对其进行任何配置即可工作。从 Angular $location 文档中,您可以看到后备方法及其工作原理。

综上所述

  • 这是获取漂亮 URL 并在 Angular 应用程序中删除主题标签的简单方法。玩得开心制作那些超级干净和超级快速的 Angular 应用程序!
于 2015-12-07T19:26:56.110 回答
4

使用 HTML5 模式需要在服务器端重写 URL,基本上你必须重写所有指向应用程序入口点的链接(例如 index.html)。在这种情况下,需要一个<base>标签也很重要,因为它允许 AngularJS 区分作为应用程序基础的 url 部分和应该由应用程序处理的路径。有关更多信息,请参阅AngularJS 开发人员指南 - 使用 $location HTML5 模式服务器端


更新

如何:配置您的服务器以使用 html5Mode 1

启用 html5Mode 后,#您的网址中将不再使用该字符。该#符号很有用,因为它不需要服务器端配置。没有#, url 看起来更好,但它也需要服务器端重写。这里有些例子:

Apache 重写

<VirtualHost *:80>
    ServerName my-app

    DocumentRoot /path/to/app

    <Directory /path/to/app>
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html to allow html5 state links
        RewriteRule ^ index.html [L]
    </Directory>
</VirtualHost>

Nginx 重写

server {
    server_name my-app;

    index index.html;

    root /path/to/app;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Azure IIS 重写

<system.webServer>
  <rewrite>
    <rules> 
      <rule name="Main Rule" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="/" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

快速重写

var express = require('express');
var app = express();

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));

app.all('/*', function(req, res, next) {
    // Just send the index.html for other files to support HTML5Mode
    res.sendFile('index.html', { root: __dirname });
});

app.listen(3006); //the port you want to use

也可以看看

于 2017-09-11T08:29:44.913 回答
3

如果您想在 OS X 10.8 上本地配置此功能,使用 Apache 为 Angular 提供服务,那么您可能会在 .htaccess 文件中找到以下帮助:

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On
    RewriteBase /~yourusername/appname/public/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !.*\.(css|js|html|png|jpg|jpeg|gif|txt)
    RewriteRule (.*) index.html [L]
</IfModule>

如果未设置选项 +FollowSymlinks 可能会在日志中给您一个禁止的错误,如下所示:

Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden

需要重写基础,否则请求将被解析到您的服务器根目录,默认情况下本地不是您的项目目录,除非您专门配置了虚拟主机,因此您需要设置路径,以便请求找到您的项目根目录。例如,在我的机器上,我有一个 /Users/me/Sites 目录,用于保存我的所有项目。就像旧的 OS X 设置一样。

接下来的两行有效地说明了路径是否不是目录或文件,因此您需要确保没有与您的应用程序路由路径相同的文件或目录。

下一个条件表示如果请求没有以指定的文件扩展名结尾,那么在此处添加您需要的内容

最后一个 [L] 表示为 index.html 文件提供服务——您的应用程序用于处理所有其他请求。

如果您仍然有问题,请检查 apache 日志,它可能会给您有用的提示:

/private/var/log/apache2/error_log
于 2014-01-31T16:19:28.447 回答
1

在 Angular 6 中,您可以使用路由器:

RouterModule.forRoot(routes, { useHash: false })
于 2018-08-30T03:12:10.223 回答
0

您还可以使用以下代码重定向到主页(主页):

{ path: '', redirectTo: 'home', pathMatch: 'full'}

如上所述指定重定向后,您可以重定向其他页面,例如:

{ path: 'add-new-registration', component: AddNewRegistrationComponent},
{ path: 'view-registration', component: ViewRegistrationComponent},
{ path: 'home', component: HomeComponent}
于 2017-05-27T14:27:18.183 回答
0

**

建议在 Angular 中使用 HTML 5 风格(PathLocationStrategy)作为定位策略

** 因为

  1. 它生成干净且对 SEO 友好的 URL,使用户更容易理解和记住。
  2. 您可以利用服务器端渲染的优势,这将使我们的应用程序加载更快,方法是先在服务器中渲染页面,然后再将其交付给客户端。

仅当您必须支持旧版浏览器时才使用 Hashlocationstrtegy。

点击这里了解更多

于 2017-12-27T12:55:48.340 回答