origin locationchangesuccess html5 spring angularjs spring-boot

locationchangesuccess - Bota de primavera con AngularJS html5Mode



redirect angularjs controller (9)

Comienzo mi aplicación web con el arranque de primavera. Utiliza una clase principal simple para iniciar un servidor tomcat incorporado:

@Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

Quiero configurar el servidor de manera que él pueda manejar el modo html5 de angularjs que se activará con

$locationProvider.html5Mode(true);

Las publicaciones relevantes de otros usuarios muestran que necesita redirigir a la raíz. El modo html5 elimina el hashbag de la url. Si actualiza la página, el servidor no encuentra la página porque no maneja el hash. vea: AngularJS - ¿Por qué al cambiar la dirección url $ routeProvider no parece funcionar y aparece un error 404?


¡Finalmente obtengo mi aplicación Angular 5 trabajando con arranque de primavera con o sin spring-boot-starter-tomcat como está incluido (incrustado) o no!

/** * Needed for html5mode (PathLocationStrategy in Angular). Every path except api/* and resources (css, html, js, woff, etc..) * should be redirect to index.html and then should angular managed routes (which could be correct or non existing). */ @RestController @RequestMapping public class ForwardController { @GetMapping(value = "/**/{[path:[^//.]*}") public ModelAndView forward() { return new ModelAndView("/index.html"); } }


1- Primero crea un nuevo Controlador, luego copia y pega código simple debajo de

@Controller public class viewController { @RequestMapping(value = "/**/{[path:[^//.]*}") public String redirect() { // Forward to home page so that route is preserved. return "forward:/"; } }

3- Elimina 2 elementos debajo de la aplicación angular

$locationProvider.hashPrefix(''!''); $urlRouterProvider.otherwise("/");

2- en la aplicación angular, debe agregar $locationProvider.html5Mode(true); a la ruta de la aplicación

3- No olvide colocar la etiqueta base antes de cualquier solicitud http en su archivo index.html

<head> <base href="/"> /* Or whatever your base path is */ //call every http request for style and other ... </head>

está bien para mí


Acabo de encontrar un problema similar en el que quería configurar los recursos y, al mismo tiempo, quería usar el modo AngularJS Html5 habilitado.

En mi caso, mis archivos estáticos fueron servidos desde /public ruta /public , así que usé la siguiente asignación de solicitud en mi acción de índice y todo funciona bien.

@RequestMapping(value = {"", "/", "/{[path:(?!public).*}/**"}, method = GET) public String indexAction() { return "index"; }


Encontré una solución con la que puedo vivir.

@Controller public class ViewController { @RequestMapping("/") public String index() { return "index"; } @RequestMapping("/app/**") public String app() { return "index"; } }

La aplicación angularjs tiene que estar bajo el subdominio. Si no quieres, puedes crear un subdominio como app.subdomain.com que se asigna a tu subdominio. Con esta construcción no tiene conflictos con los webjars, el contenido de estadísticas, etc.


Puede reenviar todos los recursos no encontrados a su página principal al proporcionar ErrorViewResolver personalizado. Todo lo que necesitas hacer es agregar esto a tu clase @Configuration:

@Bean ErrorViewResolver supportPathBasedLocationStrategyWithoutHashes() { return new ErrorViewResolver() { @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { return status == HttpStatus.NOT_FOUND ? new ModelAndView("index.html", Collections.<String, Object>emptyMap(), HttpStatus.OK) : null; } }; }


Tuve el mismo problema Por lo que sé, en el modo html5, angularjs no resuelve el hash, pero ingresó la url o la url agregada a through pushState .

El problema fue que PathResourceResolver mapea directorios pero no archivos. Porque pretendía servir los archivos solicitados desde el directorio, pero no reescribir las URL. Para la aplicación es simple, si actualiza la ventana de su navegador o escribe url como http://example.com/mystate , es la consulta "/ mystate" del servidor. Si la primavera no conoce la URL, devuelven 404. Una de las soluciones es asignar todos los estados posibles a index.html, como here ( source , por cierto, mirar webjars, ¡es genial!). Pero en mi caso, puedo asignar de forma segura "/ **" a index.html y, por lo tanto, mi solución es anular PathResourceResolver # getResource:

@Configuration @EnableConfigurationProperties({ ResourceProperties.class }) public class WebMvcConfig extends WebMvcConfigurerAdapter { @Autowired private ResourceProperties resourceProperties = new ResourceProperties(); @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { Integer cachePeriod = resourceProperties.getCachePeriod(); registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/static/") .setCachePeriod(cachePeriod); registry.addResourceHandler("/**") .addResourceLocations("classpath:/static/index.html") .setCachePeriod(cachePeriod).resourceChain(true) .addResolver(new PathResourceResolver() { @Override protected Resource getResource(String resourcePath, Resource location) throws IOException { return location.exists() && location.isReadable() ? location : null; } }); } }


Tuve el mismo problema al usar angular Html5Mode. La solución que funcionó para mí fue configurar la página de error 404 en web.xml asignando la ruta a mi vista de índice en mi caso "/".

<error-page> <error-code>404</error-code> <location>/</location> </error-page>

Del mismo modo, puede intentar configurar la página de error en el arranque de primavera. Para referencia, puedes consultar este enlace.

Inicio de primavera y página de error 404 personalizada


Un pequeño ajuste a un código anterior que me funciona.

// Running with Spring Boot v1.3.0.RELEASE, Spring v4.2.3.RELEASE @Configuration @EnableConfigurationProperties({ ResourceProperties.class }) public class WebMvcConfig extends WebMvcConfigurerAdapter { @Autowired private ResourceProperties resourceProperties = new ResourceProperties(); @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { Integer cachePeriod = resourceProperties.getCachePeriod(); final String[] staticLocations = resourceProperties.getStaticLocations(); final String[] indexLocations = new String[staticLocations.length]; for (int i = 0; i < staticLocations.length; i++) { indexLocations[i] = staticLocations[i] + "index.html"; } registry.addResourceHandler( "/**/*.css", "/**/*.html", "/**/*.js", "/**/*.json", "/**/*.bmp", "/**/*.jpeg", "/**/*.jpg", "/**/*.png", "/**/*.ttf", "/**/*.eot", "/**/*.svg", "/**/*.woff", "/**/*.woff2" ) .addResourceLocations(staticLocations) .setCachePeriod(cachePeriod); registry.addResourceHandler("/**") .addResourceLocations(indexLocations) .setCachePeriod(cachePeriod) .resourceChain(true) .addResolver(new PathResourceResolver() { @Override protected Resource getResource(String resourcePath, Resource location) throws IOException { return location.exists() && location.isReadable() ? location : null; } }); }

}


Utilice este controlador para reenviar el URI a index.html para conservar las rutas de AngularJS. Fuente https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii

@Controller public class ForwardController { @RequestMapping(value = "/**/{[path:[^//.]*}") public String redirect() { // Forward to home page so that route is preserved. return "forward:/"; } }

En esta solución, ForwardController reenvía solo las rutas, que no están definidas en ningún otro Controller ni RestController . Significa si ya tienes:

@RestController public class OffersController { @RequestMapping(value = "api/offers") public Page<OfferDTO> getOffers(@RequestParam("page") int page) { return offerService.findPaginated(page, 10); } }

ambos controladores van a funcionar correctamente: @RequestMapping(value = "api/offers") se comprueba antes de @RequestMapping(value = "/**/{[path:[^//.]*}")