从 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。
我需要将 请务必检查浏览器对 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 中,我将此添加到 <head>
<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:<head> <base href="/"> </head>
然后,在您的 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 && window.history.pushState) ...
例如:如果点击:<a href="/other">Some URL</a>
在 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> <base href="/"> </b>
对于不支持 HTML5 History API 的浏览器,$location 服务将自动回退到 hash-part 方法。
【讨论】:
【参考方案11】:第 1 步:将 $locationProvider 服务注入应用配置的构造函数
第 2 步:将代码行 $locationProvider.html5Mode(true) 添加到应用配置的构造函数中。
第三步:在容器(登陆、主控或布局)页面中,在标签内添加<base href="/">
等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 开始,从 <a href="#/aboutus">About Us</a>
中删除所有 #
,所以它必须看起来像 <a href="/aboutus">About Us</a>
。现在在 index.html 的头部标签中,在最后一个 元标签之后写入 <base href="/">
.
现在在你的路由中注入 $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 中删除片段标识符(# 符号)的主要内容,如果未能解决你的问题,请参考以下文章
Linkedin OAuth 2.0 重定向 URL 不能包含片段标识符 (#)
如何从 URL、Spring Boot 和 AngularJs 应用程序中删除 #?