Soy novato usando Angular HttpClient (y escribiendo en inglés también)

Tengo un problema, estoy intentando enviar una solicitud HTTP con el método POST para negociar la obtención del token OAuth, pero angular envía la solicitud OPTIONS:

Servicio:

login(username: string, password: string) {
const body = `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&grant_type=password`;

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic ' + btoa(TOKEN_AUTH_USERNAME + ':' + TOKEN_AUTH_PASSWORD)
  })
};  


return this.http.post<string>(AuthenticationService.AUTH_TOKEN, body, httpOptions);

Resultado:

enter image description here

Para mi backend, estoy usando Spring Security y agregué un filtro para permitir CORS:

@Bean
public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(0);
    return bean;
}
5
Jose A. Matarán 27 feb. 2018 a las 17:40

6 respuestas

La mejor respuesta

No tiene relación angular, lo está haciendo su navegador.

Verifique este problema.

Supongo que su servidor se ejecuta en localhost: 8080, y su aplicación angular en localhost: 4200. Como su solicitud es de origen cruzado, el navegador primero envía una solicitud OPTIONS para ver si es segura. En este punto, su servidor devuelve una respuesta con el código http 401 que evita que se realice la solicitud posterior. O tiene que hacer alguna configuración en su servidor o puede usar el proxy webpack. Esto es solo para su máquina local. Si sirve su aplicación angular incluida desde su servidor, entonces no tendrá que hacer nada para la producción. He estado usando esta técnica durante bastante tiempo, y funciona bien.

Ejemplo,

Los usuarios acceden a mi aplicación angular desde mydomain.com/ng-app También sirvo mi API de descanso desde el mismo dominio, mydomain.com/api

Por lo tanto, mi aplicación siempre realiza la solicitud al servidor desde el que se está sirviendo, lo que no causa problemas en la producción.

Para esto último, puedes hacer lo siguiente

Cree un proxy.conf.json en la raíz de su proyecto (al lado de package.json) Y poner seguimiento dentro

{
    "/api/": {
        "target": "http://localhost:8080",
        "secure": false,
        "changeOrigin": true
    }
}

En package.json, edite su script start y hágalo ng serve --proxy-config proxy.conf.json

Además, desde su interfaz, no envíe las solicitudes a localhost: 8080 directamente, solo escriba algo como http.post('/api/getSomeData') que hará la solicitud a localhost: 4200 que lo redirigirá a localhost: 8080. De esta manera, no tendrá que lidiar con CORS.

11
Bunyamin Coskuner 27 feb. 2018 a las 15:14

Finalmente encontré el error. El orden del filtro no era correcto. Lo ajusté a Ordered.HIGHEST_PRECEDENCE de esta manera anula el filtro Spring.

@Bean
public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
}
-1
Jose A. Matarán 27 feb. 2018 a las 21:36

Con un backend NestJS / Express, arreglé esto habilitando CORS: https: //docs.nestjs. com / technologies / security # cors

0
angristan 26 abr. 2020 a las 16:16

Usar configuración angular cli https://angular.io/guide/build#proxying-to- un servidor backend

0
Mahmoud Hboubati 11 abr. 2020 a las 20:22

Para la aplicación de arranque de primavera, para habilitar la solicitud de cors, use @CrossOrigin (origins = "*", maxAge = 3600) en su controlador respectivo.

Refiera esto

0
Chintan Pandya 13 mar. 2019 a las 14:17

La solicitud OPTIONS se envía primero debido a CORS, Angular necesita permiso de su servidor para saber si puede POST. Por lo tanto, en su back-end, debe habilitar CORS para que la solicitud http se envíe.

0
Mike Tung 27 feb. 2018 a las 14:44