Javascript 没有哈希'#'的AngularJS路由

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14319967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 16:22:09  来源:igfitidea点击:

AngularJS routing without the hash '#'

javascriptangularjs

提问by pikkvile

I'm learning AngularJS and there's one thing that really annoys me.

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

I use $routeProviderto declare routing rules for my application:

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

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

but when I navigate to my app in browser I see app/#/testinstead of app/test.

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

So my question is why AngularJS adds this hash #to urls? Is there any possibility to avoid it?

所以我的问题是为什么 AngularJS 会将此哈希添加#到 url 中?有没有可能避免它?

回答by plus-

In fact you need the # (hashtag) for non HTML5 browsers.

事实上,对于非 HTML5 浏览器,您需要 #(hashtag)。

Otherwise they will just do an HTTP call to the server at the mentioned href. The # is an old browser shortcircuit which doesn't fire the request, which allows many js frameworks to build their own clientside rerouting on top of that.

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

You can use $locationProvider.html5Mode(true)to tell angular to use HTML5 strategy if available.

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

Here the list of browser that support HTML5 strategy: http://caniuse.com/#feat=history

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

回答by bearfriend

If you enabled html5mode as others have said, and create an .htaccessfile with the following contents (adjust for your needs):

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

Users will be directed to the your app when they enter a proper route, and your app will read the route and bring them to the correct "page" within it.

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

EDIT: Just make sure not to have any file or directory names conflict with your routes.

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

回答by vijay

Lets write answer that looks simple and short

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

In Router at end add html5Mode(true);

在路由器末尾添加html5Mode(true);

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

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

    $locationProvider.html5Mode(true);
})

In html head add basetag

在 html head 中添加base标签

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

thanks To @plus- for detailing the above answer

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

回答by skeep

try

尝试

$locationProvider.html5Mode(true)

More info at $locationProvider
Using $location

更多信息在 $locationProvider
使用 $location

回答by zero_cool

The following information is from:
https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag

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

It is very easy to get clean URLs and remove the hashtag from the URL in Angular.
By default, AngularJS will route URLs with a hashtag For Example:

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

There are 2 things that need to be done.

有两件事需要做。

  • Configuring $locationProvider

  • Setting our base for relative links

  • $location Service

  • 配置 $locationProvider

  • 设置我们的相对链接基础

  • $定位服务

In Angular, the $location service parses the URL in the address bar and makes changes to your application and vice versa.

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

I would highly recommend reading through the official Angular $location docs to get a feel for the location service and what it provides.

我强烈建议通读官方的 Angular $location 文档,以了解定位服务及其提供的内容。

https://docs.angularjs.org/api/ng/service/$location

https://docs.angularjs.org/api/ng/service/$location

$locationProvider and html5Mode

$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); });
    
  • 我们将使用 $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); });
    

What is the HTML5 History API? It is a standardized way to manipulate the browser history using a script. This lets Angular change the routing and URLs of our pages without refreshing the page. For more information on this, here is a good HTML5 History API Article:

什么是 HTML5 历史 API?这是使用脚本操纵浏览器历史记录的标准化方法。这让 Angular 可以在不刷新页面的情况下更改我们页面的路由和 URL。有关这方面的更多信息,这里有一篇很好的 HTML5 History API 文章:

http://diveintohtml5.info/history.html

http://diveintohtml5.info/history.html

Setting For Relative Links

相对链接的设置

  • To link around your application using relative links, you will need to set the <base>in the <head>of your document. This may be in the root index.html file of your Angular app. Find the <base>tag, and set it to the root URL you'd like for your app.
  • 要使用相对链接围绕您的应用程序进行链接,您需要<base><head>文档的 中设置 。这可能位于 Angular 应用程序的根 index.html 文件中。找到该<base>标签,并将其设置为您的应用所需的根 URL。

For example: <base href="/">

例如: <base href="/">

  • There are plenty of other ways to configure this, and the HTML5 mode set to true should automatically resolve relative links. If your root of your application is different than the url (for instance /my-base, then use that as your base.
  • 还有很多其他方法可以配置它,设置为 true 的 HTML5 模式应该会自动解析相关链接。如果您的应用程序的根目录与 url 不同(例如 /my-base,则将其用作基础。

Fallback for Older Browsers

旧浏览器的回退

  • The $location service will automatically fallback to the hashbang method for browsers that do not support the HTML5 History API.
  • This happens transparently to you and you won't have to configure anything for it to work. From the Angular $location docs, you can see the fallback method and how it works.
  • 对于不支持 HTML5 History API 的浏览器,$location 服务将自动回退到 hashbang 方法。
  • 这对您来说是透明的,您无需对其进行任何配置即可工作。从 Angular $location 文档中,您可以看到回退方法及其工作原理。

In Conclusion

综上所述

  • This is a simple way to get pretty URLs and remove the hashtag in your Angular application. Have fun making those super clean and super fast Angular apps!
  • 这是获取漂亮 URL 并删除 Angular 应用程序中的主题标签的简单方法。享受制作那些超级干净和超级快速的 Angular 应用程序的乐趣!

回答by georgeawg

Using HTML5 mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base>tag is also important for this case, as it allows AngularJS to differentiate between the part of the url that is the application base and the path that should be handled by the application. For more information, see AngularJS Developer Guide - Using $location HTML5 mode Server Side.

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



Update

更新

How to: Configure your server to work with html5Mode1

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

When you have html5Mode enabled, the #character will no longer be used in your urls. The #symbol is useful because it requires no server side configuration. Without #, the url looks much nicer, but it also requires server side rewrites. Here are some examples:

启用 html5Mode 后,#您的网址中将不再使用该字符。该#符号很有用,因为它不需要服务器端配置。没有#,url 看起来更好,但它也需要服务器端重写。这里有些例子:

Apache Rewrites

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

Nginx 重写

server {
    server_name my-app;

    index index.html;

    root /path/to/app;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Azure IIS Rewrites

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>

Express Rewrites

快速重写

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

See also

也可以看看

回答by Mister P

If you are wanting to configure this locally on OS X 10.8 serving Angular with Apache then you might find the following in your .htaccess file helps:

如果您想在 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 if not set may give you a forbidden error in the logs like so:

选项 +FollowSymlinks 如果未设置可能会在日志中给您一个禁止的错误,如下所示:

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

Rewrite base is required otherwise requests will be resolved to your server root which locally by default is not your project directory unless you have specifically configured your vhosts, so you need to set the path so that the request finds your project root directory. For example on my machine I have a /Users/me/Sites directory where I keep all my projects. Like the old OS X set up.

需要重写基础,否则请求将被解析到您的服务器根目录,默认情况下本地不是您的项目目录,除非您专门配置了虚拟主机,因此您需要设置路径,以便请求找到您的项目根目录。例如,在我的机器上,我有一个 /Users/me/Sites 目录,用于保存我所有的项目。就像旧的 OS X 设置一样。

The next two lines effectively say if the path is not a directory or a file, so you need to make sure you have no files or directories the same as your app route paths.

接下来的两行有效地说明了路径是否不是目录或文件,因此您需要确保没有与应用程序路由路径相同的文件或目录。

The next condition says if request not ending with file extensions specified so add what you need there

下一个条件表示如果请求未以指定的文件扩展名结尾,则在那里添加您需要的内容

And the [L] last one is saying to serve the index.html file - your app for all other requests.

[L] 最后一个是说为 index.html 文件提供服务 - 您的应用程序用于所有其他请求。

If you still have problems then check the apache log, it will probably give you useful hints:

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

/private/var/log/apache2/error_log

回答by gpresland

In Angular 6, with your router you can use:

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

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

回答by Mahendra Waykos

**

**

It is recommended to use the HTML 5 style (PathLocationStrategy) as location strategy in Angular

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

** Because

** 因为

  1. It produces the clean and SEO Friendly URLs that are easier for users to understand and remember.
  2. You can take advantage of the server-side rendering, which will make our application load faster, by rendering the pages in the server first before delivering it the client.
  1. 它生成干净且 SEO 友好的 URL,用户更容易理解和记住。
  2. 您可以利用服务器端渲染,这将使我们的应用程序加载速度更快,方法是先在服务器中渲染页面,然后再将其交付给客户端。

Use Hashlocationstrtegy only if you have to support the older browsers.

Click here to know more

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

点击这里了解更多

回答by Arash

You could also use the below code to redirect to the main page (home):

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

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

After specifying your redirect as above, you can redirect the other pages, for example:

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

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