进入特定Angular 2.0 SPA状态的外部链接不起作用

Bra*_*don 8 iis html5 url-rewriting angular2-routing angular

我正在使用AngularJS 2.4.6,Typescript 2.1.2,IIS 8.0,Chrome,Visual Studio 2015

我正在使用Angular Heroes教程并注意到当我刷新浏览器时我得到了404响应(由于PathLocationStrategy -aka HTML5路径 - 默认使用)...所以这是有道理的,因为IIS看不到/仪表板返回.

有很多解决方案使用URL重写,我做了,确实正确地路由到index.html.

我的问题是,当我刷新浏览器时,我希望它处于相同的状态.这与使用哈希策略的角度1.5一样好用.

我是否需要做一些特定的事情来创建这种行为?原样(Angular 2.0),刷新结束导致基本状态显示而不是我所在的状态.

我注意到Rewrite操作将301发送回浏览器,因此index.html再次不知道预期的状态.

重要的是,外部链接(例如,从电子邮件中)到Angular 2 app特定状态的工作方式如何?

例如,如果我发送一封包含我的应用程序链接的电子邮件,例如:
https:// myserver/some/path/to/aState

这个简单的场景似乎不适用于我尝试过的所有内容.

该项目不涉及MVC.客户端代码向webapi middletier web发出ajax请求,但出于我要求的目的,你可以假设根本没有http调用.

Bur*_*sci 0

我假设您使用 Visual Studio 2015 开发解决方案ASP.NET MVC在解决方案的根目录中使用 index.html ,至少具有如下文件/文件夹结构:

- /Controllers
- index.html
- /src/app/ (Angular source)
- web.config
Run Code Online (Sandbox Code Playgroud)

步骤1:web.config配置

将以下内容添加rewrite rulessystem.webServerweb.config 部分:

<system.webServer>
  <rewrite>
    <rules>
      <rule name="clientRewrite rule" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" ignoreCase="true" negate="true" />      
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/assets/" ignoreCase="true" negate="true" />
        </conditions>
        <action type="Rewrite" url="/" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

此配置会将所有请求(/api 和/assets 除外)重定向到您的index.html。您可以自定义此行为。

另外,不要忘记webpages启用appSettings

<add key="webpages:Enabled" value="false" />
Run Code Online (Sandbox Code Playgroud)

编辑

在“编译”部分添加buildProviders扩展。htmlsystem.web

<buildProviders>
  <add extension=".html" type="System.Web.WebPages.Razor.RazorBuildProvider, System.Web.WebPages.Razor" />
</buildProviders>
Run Code Online (Sandbox Code Playgroud)

第2步:index.html

确保在 index.html 的标签base href之间包含, :<head> ... </head>

<base href="/">
Run Code Online (Sandbox Code Playgroud)

步骤3:Global.asax配置

您需要注册html扩展。只需将以下方法添加到 Global.asax.cs 中:

public static void RegisterHtmlExtension()
{
    RazorCodeLanguage.Languages.Add("html", new CSharpRazorCodeLanguage());
    WebPageHttpHandler.RegisterExtension("html");
}
Run Code Online (Sandbox Code Playgroud)

并调用RegisterHtmlExtension();Application_Start()方法。

您不需要为您的angular views(模板)注册路线。以下(最小)服务器路由配置就足够了:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("favicon.ico");
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    //register custom routes (extensions, etc)
    var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>();
    routePublisher.RegisterRoutes(routes);
}
Run Code Online (Sandbox Code Playgroud)

如果您有 WebAPI 控制器,您可能需要为它们进行适当的路由配置。此配置应该有效:

public static class WebApiRouteProvider
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            "DefaultApi",
            "api/{controller}/{id}",
            new { area = "api", id = RouteParameter.Optional }
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

并且,您必须通过GlobalConfiguration.Configure(WebApiRouteProvider.Register);Application_Start()方法中调用来注册这些路由。

结论

这样,您就可以将所有请求重定向到index.html(重写规则中明确定义的路径除外)。

并且,Angular 将能够拦截具有给定路径的所有请求(例如:http://yoursite.com/about/ushttp://yoursite.com/account/login等),这将导致渲染具有给定路径的组件路线。