Cómo agregar una solicitud CORS en el encabezado en Angular 5

84

He agregado el CORS en el encabezado pero todavía recibo el problema CORS en mi solicitud. ¿Cuál es la forma correcta de agregar y manejar CORS y otras solicitudes en los encabezados?

Aquí está el código del archivo de servicio:

import { HttpClient, HttpHeaders, HttpClientModule } from '@angular/common/http';
const httpOptions = {
  headers: new HttpHeaders({ 
    'Access-Control-Allow-Origin':'*',
    'Authorization':'authkey',
    'userid':'1'
  })
};

public baseurl = 'http://localhost/XXXXXX';

userAPI(data): Observable<any> {
  return this.http.post(this.baseurl, data, httpOptions)
    .pipe(
      tap((result) => console.log('result-->',result)),
      catchError(this.handleError('error', []))
    );
}

Error:

La respuesta a la solicitud de verificación previa no pasa la verificación de control de acceso: no hay un encabezado 'Access-Control-Allow-Origin' presente en el recurso solicitado. Por lo tanto, no se permite el acceso al origen ' http: // localhost: 4200 '

Error: respuesta de error de Http para (URL desconocida): 0 Error desconocido

En mi código del lado del servidor, agregué CORS en el archivo de índice.

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
Aman Kumar
fuente
3
Necesita agregar los encabezados de Cors en el lado del servidor.
Sachila Ranawaka
@SachilaRanawaka Sí, lo he agregado en mi archivo de índice.
Aman Kumar
publicar ese archivo de servidor
Sachila Ranawaka
Esta respuesta puede ser útil: stackoverflow.com/a/58064366/7059557
AmirReza-Farahlagha

Respuestas:

49

En mi experiencia, los complementos funcionaron con HTTP pero no con el último httpClient. Además, configurar los encabezados de respuesta CORS en el servidor no era realmente una opción. Entonces, creé un proxy.conf.jsonarchivo para actuar como servidor proxy.

Lea más sobre esto aquí .

proxy.conf.json archivo:

{
  "/posts": {
    "target": "https://example.com",
    "secure": true,
    "pathRewrite": {
    "^/posts": ""
  },
    "changeOrigin": true
  }
}

Coloqué el proxy.conf.jsonarchivo justo al lado del package.jsonarchivo en el mismo directorio.

Luego modifiqué el comando de inicio en el archivo package.json:

"start": "ng serve --proxy-config proxy.conf.json"

La llamada HTTP desde el componente de mi aplicación:

return this._http.get('/posts/pictures?method=GetPictures')
.subscribe((returnedStuff) => {
  console.log(returnedStuff);
});

Por último, para ejecutar mi aplicación, tendría que usar npm startong serve --proxy-config proxy.conf.json

rgantla
fuente
13
Funciona solo con fines de desarrollo. No puede crear su aplicación con esa herramienta de proxy
GVArt
¿Podría alguien de aquí echar un vistazo a la pregunta en stackoverflow.com/questions/55429787/…
Nelson King
¿Qué debemos configurar targetcomo en el archivo proxy.config?
A-Sharabiani
Lo até mostrando el estado correcto pero ahora obteniendo un nuevo error. HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:4200/", ok: false, …} error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) message: "Unexpected token < in JSON at position 0" "
Aman Gupta
6
esto no funciona en las compilaciones de producción, por lo que no puede ser una solución adecuada
Aaron Matthews
4

También puede probar la fetchfunción y el no-corsmodo. A veces me resulta más fácil configurarlo que el módulo http integrado de Angular. Puede hacer clic con el botón derecho en las solicitudes en la pestaña de red de herramientas de desarrollo de Chrome y copiarlas en la sintaxis de recuperación, lo cual es excelente.

import { from } from 'rxjs';

// ...

result = from( // wrap the fetch in a from if you need an rxjs Observable
  fetch(
    this.baseurl,
    {
      body: JSON.stringify(data)
      headers: {
        'Content-Type': 'application/json',
      },
      method: 'POST',
      mode: 'no-cors'
    }
  )
);
metakermit
fuente
El código de la pregunta intenta leer la respuesta. no-corsbloquea eso. También bloquea la configuración del tipo de contenido en application/json.
Quentin
Caso muy específico, para api.github.com/orgs/nesign/repos , vi que Access to XMLHttpRequest at '..' from origin '..' has been blocked by CORS policy: Request header field x-timezone is not allowed by Access-Control-Allow-Headers in preflight response.no se podía anular lo Access-Control-Request-Headers: cache-control,x-timezoneque se agregó de forma predeterminada :( y Github tiene esto en respuesta, la Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Accept-Encoding, X-GitHub-OTP, X-Requested-With, User-Agentbúsqueda funcionó
Anand Rockzz
¡Ups! se añadió por mí x-zona horaria - Me había sobre ingeniería del httpclientcon una vuelta mucho tiempo interceptor :)
Anand Rockzz
3

Si es como yo y está utilizando un servidor de puerta de enlace SMS local y realiza una solicitud GET a una IP como 192.168.0.xx, obtendrá un error CORS seguro.

Desafortunadamente, no pude encontrar una solución Angular, pero con la ayuda de una repetición anterior obtuve mi solución y estoy publicando una versión actualizada para Angular 7 8 9

import {from} from 'rxjs';

getData(): Observable<any> {
    return from(
      fetch(
        'http://xxxxx', // the url you are trying to access
        {
          headers: {
            'Content-Type': 'application/json',
          },
          method: 'GET', // GET, POST, PUT, DELETE
          mode: 'no-cors' // the most important option
        }
      ));
  }

Simplemente .subscríbete como de costumbre.

Avram Virgil
fuente
2

Haga que el encabezado se vea así para HttpClient en NG5:

let httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'apikey': this.apikey,
        'appkey': this.appkey,
      }),
      params: new HttpParams().set('program_id', this.program_id)
    };

Podrás hacer una llamada api con tu url localhost, funciona para mí.

  • Por favor, nunca olvide su columna de parámetros en el encabezado: como params: new HttpParams (). Set ('program_id', this.program_id)
Damon Wu
fuente
2

Una POST con httpClient en Angular 6 también estaba haciendo una solicitud de OPCIONES:

Encabezados generales:

URL de solicitud: https: //hp-probook/perl-bin/muziek.pl/=/postData
Método de solicitud: OPCIONES
Código de estado: 200 OK
Dirección remota: 127.0.0.1: 443
Política de referencias: sin referencia cuando se baja de categoría

Mi servidor REST de Perl implementa la solicitud OPTIONS con el código de retorno 200.

El siguiente encabezado de solicitud POST:

Aceptar:*/*
Aceptar codificación: gzip, deflate, br
Aceptar-Idioma: nl-NL, nl; q = 0.8, en-US; q = 0.6, en; q = 0.4
Encabezados de solicitud de control de acceso: tipo de contenido
Método de solicitud de control de acceso: POST
Conexión: mantener vivo
Anfitrión: hp-probook
Origen: http: // localhost: 4200
Referente: http: // localhost: 4200 /
Usuario-Agente: Mozilla / 5.0 (X11; Linux x86_64) AppleWebKit / 537.36 (KHTML, como Gecko) Chrome / 59.0.3071.109 Safari / 537.36

Observe los encabezados de solicitud de control de acceso: tipo de contenido.

Entonces, mi script perl backend usa los siguientes encabezados:

 - "Access-Control-Allow-Origin" => '*',
 - "Access-Control-Allow-Methods" => 'OBTENER, PUBLICAR, PATCH, ELIMINAR, PONER, OPCIONES',
 - "Access-Control-Allow-Headers" => 'Origen, tipo de contenido, X-Auth-Token, tipo de contenido',

¡Con esta configuración, GET y POST funcionaron para mí!

Rob Lassche
fuente
1

por favor, importe las solicitudes de parada de angular cors

    import {RequestOptions, Request, Headers } from '@angular/http';

y agregue opciones de solicitud en su código como se indica a continuación

    let requestOptions = new RequestOptions({ headers:null, withCredentials: 
    true });

enviar la opción de solicitud en su solicitud de api

fragmento de código a continuación

     let requestOptions = new RequestOptions({ headers:null, 
     withCredentials: true });
     return this.http.get(this.config.baseUrl + 
     this.config.getDropDownListForProject, requestOptions)
     .map(res => 
     {
      if(res != null)
      { 
        return res.json();
        //return true;
      }
    })
  .catch(this.handleError);
   }  

y agregue CORS en su código PHP backend donde todas las solicitudes de API aterrizarán primero.

intente esto y avíseme si está funcionando o no.Tuve el mismo problema.Estaba agregando CORS de angular5 que no funcionaba, luego agregué CORS al backend y funcionó para mí

raj yadav
fuente
-5

Lo siguiente funcionó para mí después de horas de intentarlo

      $http.post("http://localhost:8080/yourresource", parameter, {headers: 
      {'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' } }).

Sin embargo, el siguiente código no funcionó, no tengo claro por qué, espero que alguien pueda mejorar esta respuesta.

          $http({   method: 'POST', url: "http://localhost:8080/yourresource", 
                    parameter, 
                    headers: {'Content-Type': 'application/json', 
                              'Access-Control-Allow-Origin': '*',
                              'Access-Control-Allow-Methods': 'POST'} 
                })
Desarrollador MG
fuente
1
$ http? ¿Es AngularJS, porque estamos hablando de Angular 5 allí? No se pudo hacer que este código funcionara
Victor Jozwicki
@VictorJozwicki Tienes razón, no es Angular 5. En mi package.json muestra la versión angular 1.7.5.
MG Developer