从AngularJS网址中删除片段标识符(#符号)


257

是否可以从angular.js URL中删除#符号?

当我更改视图并使用参数更新URL时,我仍然希望能够使用浏览器的后退按钮等,但是我不希望使用#符号。

教程routeProvider声明如下:

angular.module('phonecat', []).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
  when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
  when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
  otherwise({redirectTo: '/phones'});
}]);

如果没有#,我可以对其进行编辑以具有相同的功能吗?


13
主题标签不错的人
BoJack Horseman 2014年


对我来说,这里的所有答案都是错误的。我们可以“重写” URL并删除#,但是在没有#的情况下切勿直接访问网页。任何真正的解决方案在这里?
amdev '16

如果您使用的是Angular 1.6,这是解决方案
Mistalis

Answers:


251

是的,您应该配置$locationProvider并设置html5Modetrue

angular.module('phonecat', []).
  config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {

    $routeProvider.
      when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});

    $locationProvider.html5Mode(true);

  }]);

10
由于IE lt 10不支持通过设置启用的html5历史记录API html5Mode(true)。在IE中,您必须#在路由中使用。
Maxim Grach 2013年

10
@powtac IE lt 10表示Internet Explorer低于版本10
Maxim Grach

6
您可以设置它,以便回退到在IE中使用#吗?它是那么简单,只是包裹$locationProvider.html5Mode(true);if !(IE lt 10)
安迪·海登

52
因此,此解决方案确实解决了在给定URL具有井号的情况下删除URL中的井号的问题,但是它并没有解决如何响应不希望井号包含在首位的请求。又名,它解决了blah /#/ phones- > blah / phones,但是它不能直接处理blah / phones
路加福音

9
我需要在index.html <head>部分中放入<base href =“ /” />。
nyxz 2015年

55

确保检查浏览器对html5历史记录API的支持:

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }

23
这可能更适合作为注释,因为它不能直接回答问题。
brandonscript

31
根据开发人员指南,该检测是自动完成的:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB 2014年

像魅力一样工作,我很欣赏方法检查,而不是浏览器版本检查,这是未来的证明。
Shane 2014年

46

要删除漂亮的URL的Hash标签以及最小化后代码,您需要像下面的示例所示构建代码:

jobApp.config(['$routeProvider','$locationProvider',
    function($routeProvider, $locationProvider) {
        $routeProvider.
            when('/', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus/:id', {
                templateUrl: 'views/job-detail.html',
                controller: 'JobDetailController'
            });

         //you can include a fallback by  including .otherwise({
          //redirectTo: '/jobs'
        //});


        //check browser support
        if(window.history && window.history.pushState){
            //$locationProvider.html5Mode(true); will cause an error $location in HTML5 mode requires a  tag to be present! Unless you set baseUrl tag after head tag like so: <head> <base href="https://stackoverflow.com/">

         // to know more about setting base URL visit: https://docs.angularjs.org/error/$location/nobase

         // if you don't wish to set base URL then use this
         $locationProvider.html5Mode({
                 enabled: true,
                 requireBase: false
          });
        }
    }]);

15
对于requireBase: false+1
whoan,2016年

2
您好@digitlimit,添加$locationProvider.html5Mode代码后,我的代码$urlRouterProvider.otherwise('/home');停止工作。
Jaikrat

18

$locationProvider.html5Mode(true)中设置后,我在web.config中写出一条规则app.js

希望能帮助某人。

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

在我的index.html中,我将此添加到了 <head>

<base href="/">

不要忘记在服务器上为iis安装URL重写器。

另外,如果您使用Web Api和IIS,则此匹配网址将无法工作,因为它将更改您的api调用。因此,添加第三个输入(条件的第三行)并给出一种模式,该模式将排除来自www.yourdomain.com/api


1
如何为IIS安装URL重写器?我在Azure上托管。
Prabhu 2015年

11

如果您在带有AngularJS的MVC的.NET堆栈中,则必须执行以下操作以从URL中删除“#”:

  1. 在_Layout页面中设置基本href: <head> <base href="https://stackoverflow.com/"> </head>

  2. 然后,在您的angular应用程序配置中添加以下内容: $locationProvider.html5Mode(true)

  3. 上面的代码会从网址中删除“#”,但是页面刷新将无法进行,例如,如果您位于“ yoursite.com/about”页面中,则刷新将为您提供404。这是因为MVC不了解角度路由,而按MVC模式会在MVC路由路径中查找“ about”的MVC页面。解决方法是将所有MVC页面请求发送到单个MVC视图,您可以通过添加捕获所有MVC页面请求的路由来实现

网址:

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);

我应该在哪个文件中添加routes.MapRoute?
Vicheanak,2015年

1
RouteConfig.cs在App_Start文件夹下
Maksood,2015年

5

您可以调整html5mode,但这仅适用于页面的html锚点中包含的链接以及该URL在浏览器地址栏中的外观。尝试从页面外部的任何地方请求不包含井号(带有或不带有html5mode)的子页面将导致404错误。例如,无论html5mode如何,以下CURL请求都将导致找不到页面错误:

$ curl http://foo.bar/phones

尽管以下内容将返回根/主页:

$ curl http://foo.bar/#/phones

原因是在请求到达服务器之前,剥离了#标签之后的所有内容。因此,对的请求会作为对的请求http://foo.bar/#/portfolio到达服务器http://foo.bar。服务器将以200 OK响应(大概)做出响应http://foo.bar,代理/客户端将处理其余的响应。

因此,如果您想与他人共享网址,则别无选择,只能包含井号。


有没有办法解决?这是一个很大的问题。
user441521 '16

5

遵循2个步骤-1
.首先在您的应用配置文件中设置$ locationProvider.html5Mode(true)
例如-
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2.然后在首页中设置<base>
例如->
<base href="https://stackoverflow.com/">

对于不支持HTML5历史记录API的浏览器,$ location服务将自动回退到hash-part方法。


3

我的解决方案是创建.htaccess并使用#Sorian代码..没有.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]

1

根据文档。您可以使用:

$locationProvider.html5Mode(true).hashPrefix('!');

注意:如果您的浏览器不支持HTML5。请不要担心:D它会回退到hashbang模式。因此,您无需if(window.history && window.history.pushState){ ... }手动检查

例如:如果您单击: <a href="https://stackoverflow.com/other">Some URL</a>

在HTML5浏览器中:angular将自动重定向到example.com/other

在非HTML5浏览器中:angular将自动重定向到example.com/#!/other


1

该答案假定您使用nginx作为反向代理,并且已经将$ locationProvider.html5mode设置为true。

->对于那些可能仍在努力解决上述所有酷问题的人们。

当然,@ maxim grach解决方案可以正常工作,但是对于如何响应那些不希望首先包含井号的请求的解决方案,可以采取的措施是检查php是否发送404,然后重写url。以下是nginx的代码,

在php位置,检测404 php错误并重定向到另一个位置,

location ~ \.php${
  ...
  fastcgi_intercept_errors on;
  error_page 404 = /redirect/$request_uri ;
}

然后在重定向位置重写url,并在脱机位置传递数据,将您的网站url放在我的博客url的位置。(要求:仅在您尝试过后才提出疑问)

location /redirect {
  rewrite ^/redirect/(.*) /$1;
  proxy_pass http://www.techromance.com;
}

并看到魔术。

它绝对有效,至少对我而言。


在哪里添加?
Volatil3

在哪里添加以上代码?将它们放在主要的Nginx配置文件中。
Satys

1

从index.html开始,将其全部删除#<a href="#/aboutus">About Us</a>因此它必须看起来像<a href="https://stackoverflow.com/aboutus">About Us</a>.Now在index.html的head标签中,紧接<base href="https://stackoverflow.com/">在最后一个meta标签之后

现在在您的路由js中注入$locationProvider并编写$locatonProvider.html5Mode(true); 如下内容:-

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when("/home", {
            templateUrl: "Templates/home.html",
            controller: "homeController"
        })
            .when("/aboutus",{templateUrl:"Templates/aboutus.html"})
            .when("/courses", {
                templateUrl: "Templates/courses.html",
                controller: "coursesController"
            })
            .when("/students", {
                templateUrl: "Templates/students.html",
                controller: "studentsController"
            })
        $locationProvider.html5Mode(true);
    });

有关更多详细信息,请观看此视频 https://www.youtube.com/watch?v=XsRugDQaGOo


删除所有#网址很有帮助,因为我在不删除#url的情况下进行了测试。
optimistanoop

1

猜猜这真的太迟了。但是将以下配置添加到app.module导入即可完成工作:

RouterModule.forRoot(routes, { useHash: false })

0

步骤1:将$ locationProvider服务注入到应用程序配置的构造函数中

步骤2:将代码行$ locationProvider.html5Mode(true)添加到应用配置的构造函数中。

步骤3:在容器(着陆,母版或版面)页面中,在标记<base href="https://stackoverflow.com/">内添加html 标记。

步骤4:从所有定位标记中删除所有用于路由配置的“#”。例如,href =“#home”变成href =“ home”; href =“#about”变成herf =“ about”; href =“#contact “成为href =“ contact”

 <ul class="nav navbar-nav">
     <li><a href="home">Home</a></li>
     <li><a href="about">About us</a></li>
     <li><a href="contact">Contact us</a></li>
</ul>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.