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

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

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

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

所以我的问题是为什么AngularJS把这个散列#添加到url ?有可能避免吗?


当前回答

如果你想在OS X 10.8和Apache上配置这个,那么你可能会在你的.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>

Options +FollowSymlinks如果没有设置,可能会在日志中给你一个禁止错误,如下所示:

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

重写base是必需的,否则请求将被解析到您的服务器根目录,在本地默认情况下不是您的项目目录,除非您特别配置了vhosts,所以您需要设置路径,以便请求找到您的项目根目录。例如,在我的机器上,我有一个/Users/me/Sites目录,其中保存了我所有的项目。就像旧的OS X设置。

接下来的两行有效地表示如果路径不是目录或文件,所以你需要确保你没有与你的应用程序路由路径相同的文件或目录。

下一个条件是,如果请求没有以指定的文件扩展名结束,那么在那里添加您需要的内容

最后一个是为index.html文件服务——你的应用程序为所有其他请求服务。

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

/private/var/log/apache2/error_log

其他回答

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

在Angular中,获取干净的URL并从URL中删除标签是非常容易的。 默认情况下,AngularJS会使用标签路由url 例如:

http://www.example.com http://www.example.com/#/about http://www.example.com/#/contact

有两件事需要做。

配置locationProvider美元 为相对链接设置基础 美元的位置服务

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

我强烈建议大家通读Angular $location的官方文档,了解一下位置服务和它提供的功能。

https://docs.angularjs.org/api/ng/service/美元位置

$locationProvider和html5Mode

We will use the $locationProvider module and set html5Mode to true. We will do this when defining your Angular application and configuring your routes. 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 History API?它是一种使用脚本操作浏览器历史记录的标准化方法。这使得Angular可以在不刷新页面的情况下更改页面的路由和url。关于这方面的更多信息,这里有一篇不错的HTML5 History API文章:

http://diveintohtml5.info/history.html

相对链接设置

要使用相对链接来链接应用程序,您将需要 在文档的<head>中设置<base>。这可能是 找到<base>标签,然后 将它设置为应用程序的根URL。

例如:<base href="/">

还有很多其他的方式来配置它,HTML5模式 设置为true将自动解析相对链接。如果你的根 与url(例如/my-base, 然后把它作为你的基础。

旧浏览器的回退

$location服务将自动回退到hashbang 方法,用于不支持HTML5 History API的浏览器。 这对您来说是透明的,您不需要配置 只要能起作用,什么都可以。在Angular的$location文档中,你可以看到 备用方法及其工作原理。

总之

这是一个简单的方法来获得漂亮的url和删除标签 你的Angular应用。做得超级干净超级好吃吗 快速的Angular应用!

如果你想在OS X 10.8和Apache上配置这个,那么你可能会在你的.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>

Options +FollowSymlinks如果没有设置,可能会在日志中给你一个禁止错误,如下所示:

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

重写base是必需的,否则请求将被解析到您的服务器根目录,在本地默认情况下不是您的项目目录,除非您特别配置了vhosts,所以您需要设置路径,以便请求找到您的项目根目录。例如,在我的机器上,我有一个/Users/me/Sites目录,其中保存了我所有的项目。就像旧的OS X设置。

接下来的两行有效地表示如果路径不是目录或文件,所以你需要确保你没有与你的应用程序路由路径相同的文件或目录。

下一个条件是,如果请求没有以指定的文件扩展名结束,那么在那里添加您需要的内容

最后一个是为index.html文件服务——你的应用程序为所有其他请求服务。

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

/private/var/log/apache2/error_log

事实上,非HTML5浏览器需要#(标签)。

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

你可以使用$locationProvider.html5Mode(true)告诉angular在可用的情况下使用HTML5策略。

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

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


更新

如何:配置您的服务器与html5Mode1工作

当你启用html5Mode时,#字符将不再在你的url中使用。符号#很有用,因为它不需要服务器端配置。如果没有#,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 Rewrites

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

另请参阅

HTML5模式与Hash模式AngularJS的优缺点 如何关闭hashbang模式

try

$locationProvider.html5Mode(true)

更多资料请浏览 locationProvider美元 使用美元的位置