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

Posted

技术标签:

【中文标题】从 AngularJS url 中删除片段标识符(# 符号)【英文标题】:Removing the fragment identifier from AngularJS urls (# symbol) 【发布时间】:2013-01-24 03:09:32 【问题描述】:

是否可以从 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');
]);

我可以编辑它以在没有#的情况下具有相同的功能吗?

【问题讨论】:

hashtag 不错的 ***.com/questions/14319967/… 对我来说,这里的所有答案都是错误的。我们可以“重写” url 并删除 #,但永远不要直接访问没有 # 的网页。这里有什么真正的解决方案??? 如果您使用的是 Angular 1.6,这里是 the solution 【参考方案1】:

是的,你应该配置$locationProvider并将html5Mode设置为true

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);

  ]);

【讨论】:

因为 IE lt 10 不支持通过设置 html5Mode(true) 启用的 html5 历史 API。在 IE 中,您必须在路由中使用 # @powtac IE lt 10 表示 Internet Explorer 低于 10 版 你可以设置它,以便回退到在 IE 中使用 # 吗?是否就像将 $locationProvider.html5Mode(true); 包裹在 if !(IE lt 10) 中一样简单? 所以这个解决方案确实解决了删除 url 中的主题标签的问题,因为 url 有一个主题标签,但是它没有解决如何响应不希望主题标签包含在第一个的请求地方。又名,它解决了blah/#/phones -> blah/phones 但它不直接处理blah/phones。 我需要将 放入我的 index.html 部分。【参考方案2】:

请务必检查浏览器对 html5 历史 API 的支持:

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

【讨论】:

这可能更适合作为评论,因为它不直接回答问题。 根据developer guide,这个检测是自动完成的:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically 工作就像一个魅力,我欣赏方法检查而不是浏览器版本检查——未来的证明。【参考方案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]

【讨论】:

【参考方案4】:

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

希望,帮助别人。

  <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 中,我将此添加到 &lt;head&gt;

<base href="/">

不要忘记在服务器上安装 iis 的 url 重写器。

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

【讨论】:

如何为 IIS 安装 url 重写器?我在 Azure 上托管。【参考方案5】:

要删除 漂亮的 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="/">

         // 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
          );
        
    ]);

【讨论】:

对于requireBase: false +1 您好@digitlimit,添加$locationProvider.html5Mode 代码后,我的代码$urlRouterProvider.otherwise('/home'); 停止工作。【参考方案6】:

您可以调整 html5mode 但这仅适用于页面的 html 锚点中包含的链接以及 url 在浏览器地址栏中的外观。尝试从页面外部的任何位置请求没有主题标签(带或不带 html5mode)的子页面将导致 404 错误。例如,以下 CURL 请求将导致页面未找到错误,与 html5mode 无关:

$ curl http://foo.bar/phones

虽然以下将返回根/主页:

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

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

因此,如果您想与他人共享网址,您别无选择,只能包含主题标签。

【讨论】:

有没有办法解决这个问题?这是一个相当大的问题。【参考方案7】:

如果您在 .NET 堆栈中使用带有 AngularJS 的 MVC,那么您必须这样做才能从 url 中删除“#”:

    在 _Layout 页面中设置基本 href:&lt;head&gt; &lt;base href="/"&gt; &lt;/head&gt;

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

    上面将从 url 中删除“#”,但页面刷新将不起作用,例如如果你在“yoursite.com/about”页面刷新会给你一个 404。这是因为 MVC 不知道角度路由,并且通过 MVC 模式,它会为 MVC 中不存在的“about”寻找 MVC 页面路由路径。解决方法是将所有 MVC 页面请求发送到单个 MVC 视图,您可以通过添加捕获所有的路由来做到这一点

网址:

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

【讨论】:

我应该在哪个文件中添加 routes.MapRoute? RouteConfig.cs 位于 App_Start 文件夹下【参考方案8】:

根据文档。您可以使用:

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

注意:如果您的浏览器不支持 HTML 5。别担心 :D 它有 回退到 hashbang 模式。所以,你不需要手动检查if(window.history &amp;&amp; window.history.pushState) ...

例如:如果点击:&lt;a href="/other"&gt;Some URL&lt;/a&gt;

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

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

【讨论】:

【参考方案9】:

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

->对于那些可能仍在为上面所有很酷的东西而苦苦挣扎的人。

当然,@maxim grach 解决方案工作正常,但是对于如何响应不希望首先包含主题标签的请求的解决方案,可以做的是检查 php 是否发送 404,然后重写网址。以下是nginx的代码,

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

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

然后在重定向位置重写 url 并 proxy_pass 数据,当然,将您的网站 url 放在我博客 url 的位置。 (要求:只有在你尝试过之后才能提出这个问题)

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

看看魔法吧。

而且它确实有效,至少对我来说是这样。

【讨论】:

在哪里添加这个? 在哪里添加上面的代码?将它们放在主要的 Nginx 配置文件中。【参考方案10】:

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

2.第二次在你的主页中设置。 例如 -> <b> &lt;base href="/"&gt; </b>

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

【讨论】:

【参考方案11】:

第 1 步:将 $locationProvider 服务注入应用配置的构造函数

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

第三步:在容器(登陆、主控或布局)页面中,在标签内添加&lt;base href="/"&gt;等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>

【讨论】:

【参考方案12】:

只需添加$locationProvider

.config(function ($routeProvider,$locationProvider)

然后添加$locationProvider.hashPrefix(''); 之后

.otherwise(
        redirectTo: '/'
      );

就是这样。

【讨论】:

【参考方案13】:

从 index.html 开始,从 &lt;a href="#/aboutus"&gt;About Us&lt;/a&gt; 中删除所有 #,所以它必须看起来像 &lt;a href="/aboutus"&gt;About Us&lt;/a&gt;。现在在 index.html 的头部标签中,在最后一个 元标签之后写入 &lt;base href="/"&gt; .

现在在你的路由中注入 $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 有帮助,因为我在测试它时没有删除 #urls。【参考方案14】:

猜猜这真的太晚了。但是将以下配置添加到 app.module 导入中就可以了:

RouterModule.forRoot(routes,  useHash: false )

【讨论】:

对 AnguarJS 提出问题!

以上是关于从 AngularJS url 中删除片段标识符(# 符号)的主要内容,如果未能解决你的问题,请参考以下文章

如何从URL获取片段标识符(hash#之后的值)?

如何从angularjs中的url中删除'#'

Linkedin OAuth 2.0 重定向 URL 不能包含片段标识符 (#)

如何从 URL、Spring Boot 和 AngularJs 应用程序中删除 #?

从 Spring @RestController 收到的 AngularJS 显示 PDF (byte[])

Watson语音到文本 - 无法构造'WebSocket':URL包含片段标识符