Is it possible to redirect 404 to index.html on Go

2019-07-14 09:10发布

I'm trying to deploy an Angular 4 app with a Java backend on Google App Engine (standard). Everything works fine except when I try to reload the page. What happens is that a request to e.g. myapp.com/some/page should be redirected to myapp.com/index.html for the Angular app to respond.

As far as I can see, this would be possible if using the app.yaml configuration file which is used for all supported languages except Java (which uses appengine-web.xml and web.xml).

Can this be done with appengine-web.xml? In any other way?

3条回答
狗以群分
2楼-- · 2019-07-14 09:48

Yes you have to use the HashLocationStrategy instead of the default PathLocationStrategy.

Angular's documentation: https://angular.io/guide/router#appendix-locationstrategy-and-browser-url-styles

Basically, you just have to tell the RouterModule to use HashLocationStrategy in your AppRoutingModule:

@NgModule({
  imports: [RouterModule.forRoot(routes, {useHash: true})],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

I hope it helps

查看更多
Summer. ? 凉城
3楼-- · 2019-07-14 10:04

If you want to keep the PathLocationStrategy which is the default "HTML5 pushState" style, you need to implement a redirect on the backend side. Basically you need to add a filter or servlet with "/*" as the URL pattern with the following behavior:

public class SinglePageAppFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        RequestDispatcher dispatcher = servletRequest.getRequestDispatcher("/");
        dispatcher.forward(servletRequest, servletResponse);
    }
}
查看更多
做自己的国王
4楼-- · 2019-07-14 10:04

As a follow up to Gwendal Le Cren's answer, I did this and needed a few more things with the filter, so I'll put them below.

// Filter all paths.
@WebFilter("/*")
public class SinglePageAppFilter implements Filter {
  @Override
  public void doFilter(
      ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
      throws IOException, ServletException {
    // Get the end part of the path e.g. /api for API requests, /devices for the devices page etc.
    String path = ((HttpServletRequest) servletRequest).getServletPath();

    // Continue with the intended action if an API request.
    if (path.startsWith("/api")) {
      filterChain.doFilter(servletRequest, servletResponse);
    } 
    // Otherwise, send the result as if requesting the '/' path.
    else {
      RequestDispatcher dispatcher = servletRequest.getRequestDispatcher("/");
      dispatcher.forward(servletRequest, servletResponse);
    }
  }

  @Override
  public void init(FilterConfig filterConfig) {}

  @Override
  public void destroy() {}
}
查看更多
登录 后发表回答