3

我目前正在使用 Angular 1.6.4 版。

为了解决hashbang我遇到的问题,我所有的 URL 都是这种格式:

http://localhost:8885/#/hotels/holiday-inn

app.js包括路由器(使用ui-router):

$urlRouterProvider.otherwise('/');
$locationProvider.hashPrefix('');
$locationProvider.html5Mode(true);

$stateProvider
    .state('index', {
        url: '/',
        templateUrl: 'index.html',
        controller: 'hotelController'
    })
    .state('login', {
        url: '/hotel/:name',
        templateUrl: 'views/hotel.html',
        controller: 'hotelController'
    });

ui-view的位于Index.cshtml(我以前拥有所有东西,_Layout.cshtml但将所有东西都移到了Index.cshtml):

<!DOCTYPE html>
<html ng-app="hotelScheduler">
<head>
    <meta charset="utf-8" />
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Application</title>
    <link href="~/css/bootstrap.min.css" rel="stylesheet" />
    <script src="~/lib/angular/angular.min.js"></script>
    <script src="~/lib/angular-ui-router/release/angular-ui-router.min.js"></script>
    <script src="~/js/app.js"></script>
    <script src="~/js/hotelController.js"></script>
</head>
<body>
    <div ui-view>
    </div>
</body>
</html>

现在我有一个不同的问题。如果我访问http://localhost:8885/hotel/holiday-inn,我会得到一个404.

为什么会这样?

其他故障排除:

如果我访问http://localhost:8885/#/hotel/,它会显示index.html而不是views/hotel.html将地址更改为http://localhost:8885/#%2Fhotel%2F. (我知道这是otherwise路由中的工作,但为什么它与一个以 hashbang 开头的 URL 一起工作?)

我一直在四处打听并在网上寻找,人们建议其余的工作是通过 C#MapRoute或服务器端代码完成的。

我将如何通过任一选项执行此操作?如果我要执行此服务器端,我如何通过 ASP.Net Core 和 Visual Studio 执行此操作?

这是我目前的MapRoute

app.UseMvc(config =>
{
    config.MapRoute(
        name: "Default",
        template: "{controller}/{action}/{id?}",
        defaults: new { controller = "App", action = "Index" }
    );
});

另一个编辑:基于评论的建议和https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode,我尝试将此代码添加到我的 web.config 以进行服务器重写

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

但是现在,绝对一切都只是重定向到根/主页:localhost:8885/.

有什么帮助吗?

4

2 回答 2

1

我在使用 AngulaJS SPA 时遇到了类似的问题,我可以使用以下代码解决:

启动.cs

app.Use(async (context, next) =>
            {
                await next();
                if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
                {
                    context.Request.Path = "/index.html";
                    await next();
                }
            })
            .UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = new List<string> { "index.html" } })
            .UseStaticFiles()
            .UseMvc();

索引.html

<base href="/" />

并且在引用 wwwroot 文件夹下的静态文件时使用正斜杠

<script src="/app.js"></script>
<script src="/app/services/auth.service.js"></script>

应用程序.js

$stateProvider
        .state('home', {
            url: '/',
            templateUrl: '/index.html',
            controller: 'HomeController',
            controllerAs: "vm"
        });

$locationProvider.html5Mode({
        enabled: true,
        requireBase: true
    });

$urlRouterProvider.otherwise('/stores');

web.config 中的 url 重写不再适用于最新的 ASP.NET 核心,您可以从 web.config 中删除该代码。

如果你使用的是 MVC,你可以试试下面的代码,虽然我没有

        app.UseStaticFiles()
           .UseMvc(routes =>
           {
               routes.MapRoute(
                   name: "default",
                   template: "{controller=Home}/{action=Index}");
               routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
           });
于 2017-08-19T10:36:17.587 回答
1

HTML5 模式下的 $location 需要一个<base>标签。

通过文档:

如果您将 $location 配置为使用 html5Mode (history.pushState),则需要使用标签指定应用程序的基本 URL,或者通过将带有 requireBase:false 的定义对象传递给 $locationProvider 来配置 $locationProvider 以不需要基本标签。 html5模式():

https://docs.angularjs.org/error/$location/nobase

解决方法是将您的$locationProvider代码更新为:

 $locationProvider.html5Mode({
     enabled: true,
     requireBase: true
 });

然后,在你的内部<head>,相应地设置你的<base>。最常见的模式是/,但您的应用程序可能需要从不同的文件夹访问资产。

<head>
  <base href="/">
  ...
</head>

或者,如果你想聪明一点,就像https://plnkr.co为引导 Angular plunks 所做的那样:

<head>
  <script>document.write('<base href="' + document.location + '" />');</script>
</head>
于 2017-05-09T21:42:45.827 回答