AngularJS路由没有哈希'#'

Posted

技术标签:

【中文标题】AngularJS路由没有哈希\'#\'【英文标题】:AngularJS routing without the hash '#'AngularJS路由没有哈希'#' 【发布时间】:2012-12-28 12:04:00 【问题描述】:

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

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

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

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

所以我的问题是为什么 AngularJS 将这个哈希 # 添加到 URL 中?有没有可能避免呢?

【问题讨论】:

如果您使用的是 Angular 1.6,这里是 the solution 【参考方案1】:

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


更新

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

启用 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

另见

Advantages/Disadvantages of HTML5 mode vs Hash mode AngularJS AngularJS - How to turn off hashbang mode

【讨论】:

【参考方案2】:

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

RouterModule.forRoot(routes,  useHash: false )

【讨论】:

【参考方案3】:

**

建议使用 HTML 5 样式(PathLocationStrategy)作为 Angular 中的定位策略

** 因为

    它生成干净且 SEO 友好的 URL,更易于 用户理解和记住。 您可以利用服务器端渲染,这将使 通过在服务器中渲染页面,我们的应用程序加载速度更快 首先在交付给客户之前。

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

Click here to know more

【讨论】:

【参考方案4】:

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

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

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

 path: 'add-new-registration', component: AddNewRegistrationComponent,
 path: 'view-registration', component: ViewRegistrationComponent,
 path: 'home', component: HomeComponent

【讨论】:

【参考方案5】:

以下信息来自: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/$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

相对链接设置

要使用相对链接链接您的应用程序,您需要 在您的文档的&lt;head&gt; 中设置&lt;base&gt;。这可能在 Angular 应用程序的根 index.html 文件。找到&lt;base&gt; 标签,然后 将其设置为您希望应用的根 URL。

例如:&lt;base href="/"&gt;

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

旧版浏览器的回退

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

结论

这是一种获取漂亮 URL 并删除其中的主题标签的简单方法 你的 Angular 应用程序。玩得开心,让那些超级干净超级 快速的 Angular 应用!

【讨论】:

【参考方案6】:

如果您像其他人所说的那样启用了 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]

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

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

【讨论】:

这个有 nginx 版本吗?当我加载 /about 时,页面会失败,除非我通过应用程序访问它。 从未使用过,但试试这个:***.com/questions/5840497/convert-htaccess-to-nginx @chovy - 这里是 nGinx 版本: server server_name my-app;根/路径/到/应用程序;位置 / try_files $uri $uri/ /index.html; 记住 在 head 标签中 谢谢!没有这个,深度链接是不可能的。如果您需要深度链接,我仍然不确定漂亮或 URI 是否值得维护它,尤其是在某些云/paas 环境中,您可能无法轻松访问 httpd 配置。【参考方案7】:

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

在Router末尾添加html5Mode(true);

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

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

    $locationProvider.html5Mode(true);
)

在html头部添加base标签

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

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

【讨论】:

我无法让它工作。我在***.com/questions/36041074/… 上发布了一个包含我的具体细节的新问题,请看一下,如果你能提供帮助,我将不胜感激。【参考方案8】:

试试

$locationProvider.html5Mode(true)

更多信息见 $locationProvider Using $location

【讨论】:

对不起,我添加了 .config(function($locationProvider) $locationProvider.html5Mode(true) ) 但我得到的结果是 index.html#%2Fhome 而不是 index.html/home【参考方案9】:

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

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

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

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

【讨论】:

好的,谢谢。这是我所怀疑的。但对我来说,这对用户来说非常不友好!假设我希望通过 url、app/res 获得一些资源。我网站的用户如何发现他们应该输入 app/#/res? 但如果是这样,为什么我需要这些路径在位置栏中可见?如果用户不使用它们,我可以制作单页 javascript 应用程序。 当您想要跟踪应用程序状态时,它很有用。这些框架提供了一种历史机制。此外,它还允许通过 url 共享直接访问应用程序的状态 在支持 HTML5 历史 API 的现代浏览器中不需要标签。请参阅@skeep 的回答和提供的链接。在 HTML5 模式下,Angular 只会在浏览器不支持的情况下使用主题标签。另请注意,如果您不想使用 $routeProvider ,则不必使用...您可以使用 ng-clicks 和 ng-include 连接自己的路由(实际上,如果您需要多个级别的路由,因为 ng-view 每页只能出现一次)。另见***.com/questions/12793609/… 对于 hashbang/pushstate/server-side 渲染 html 案例,Twitter 的内容非常好读 engineering.twitter.com/2012/12/… 它解释了他们是如何做到的,因此它向后兼容旧浏览器和搜索引擎。我知道这不是 angularjs 特定的,但您可以重现流程。【参考方案10】:

如果您想在 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>

Options +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

【讨论】:

如果您使用 MAMP 作为您的 localhost apache 服务器,请确保第一个 RewriteBase 是一个相对链接。例如RewriteBase /angularjs_site_folder/

以上是关于AngularJS路由没有哈希'#'的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS:在不完全重新加载控制器的情况下更改哈希和路由

angularjs配置路由后无法跳转

Codeigniter - AngularJS 路由导致 404

使用 AngularJS 路由时有没有办法预加载模板?

angularJs-route路由详解

AngularJs ng-route路由详解