1
votes

pourquoi je ne peux pas publier à partir de l'application angulaire locale pour redémarrer l'api de test local en cours d'exécution sur docker?

Je suis nouveau dans angular et j'ai eu cette situation dans l'une de mes classes:

J'ai une application Angular simple en cours d'exécution sur mon hôte local: 4200, depuis laquelle je veux publier un message vers une API locale RESTHEART.

Comme je l'ai appris du tutoriel RESTHEART https://restheart.org/learn/tutorial / J'ai installé Docker et téléchargé le docker-compose.yml et lors de son exécution, je le trouve dans localhost: 8080 (je crois que cette partie est ok)

J'ai essayé quelques informations sur le CORS mais je n'ai pas trouvé comment l'activer dans l'API RESTHEART. J'ai eu des informations sur le RESTHEART qui dit qu'il prend en charge CORS mais ce n'était pas un texte très clarifiant.

Je n'ai aucun problème lorsque j'essaye de publier sur https://beta.mrest.io/demo/messages , witch is not localhost

aussi, j'ai suivi les instructions dans cette page pour obtenir l'API https://restheart.org/learn/setup/ avec le exception de décommenter la ligne "- ./etc:/opt/restheart/etc:ro", car elle a généré une erreur sur les ports non valides (si vous pensez que c'est nécessaire, j'ajouterai l'erreur plus tard)

Ceci est mon ComponentService, d'où je tire la demande de publication (je ne peux pas le formater ici pour afficher le code de manière décente , je suis sory pour ça)

import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs';

const host = 'http://localhost:8080/db/coll';
// const host = 'https://beta.mrest.io/demo/messages';

@Injectable()
export class ContatoComponentService {

    constructor(private http: Http) {
    }

    enviarContato(contatoForm: any): Observable<Response> {
        const headers = new Headers();
        headers.append('key', 'demo');
        const nomeCompleto = contatoForm.nomeCompleto;
        const email = contatoForm.contato.email;
        const mensagem = 'Mensagem de teste'; //             contatoForm.mensagem;
        console.log('nomeCompleto', nomeCompleto);
        console.log('email', email);
        console.log('mensagem', mensagem);

        return this.http.post(host, {email: email, from: nomeCompleto, message: mensagem}, { headers: headers});
    }
}

Mais quand je fais la demande de publication à l'API, j'obtiens cette erreur: "Accès à XMLHttpRequest à ' http: // localhost: 8080 / db / coll 'from origin' http: // localhost: 4200 'a été bloqué par la stratégie CORS: la clé de champ d'en-tête de requête n'est pas autorisée par Access-Control-Allow-Headers dans la réponse de contrôle en amont "


0 commentaires

3 Réponses :


1
votes

Il s'agit d'un comportement normal en raison de problèmes de sécurité, vous pouvez en apprendre davantage à ce sujet et les solutions possibles sur le lien suivant https://daveceddia.com/access-control-allow-origin-cors-errors-in-angular/


0 commentaires

1
votes

Par défaut, RESTHeart envoie toujours des en-têtes CORS. Si vous le lancez simplement avec docker-compose up et que vous envoyez une requête http OPTIONS , vous devez vérifier qu'il répond correctement.

Par exemple, ci-dessous, j'ai créé une base de données "db" et une collection "coll", puis j'utilise le client httpie (mais vous pouvez utiliser curl ou n'importe quelle interface utilisateur API):

docker logs -f restheart

Voyez-vous exactement les mêmes en-têtes?

Votre message d'erreur est "La clé de champ d'en-tête de demande n'est pas autorisée par Access -Control-Allow-Headers in preflight response ": pourriez-vous vérifier votre console Javascript dans le navigateur et voir si elle reçoit une erreur après l'envoi d'une requête OPTIONS ?

De plus, rappelez-vous que lors du POST, la requête doit contenir un en-tête Accept pour application / json

http -v -a 'admin:changeit' POST http://localhost:8080/db/coll name='RESTHeart'

POST /db/coll HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Authorization: Basic YWRtaW46Y2hhbmdlaXQ=
Connection: keep-alive
Content-Length: 21
Content-Type: application/json
Host: localhost:8080
User-Agent: HTTPie/0.9.9

{
    "name": "RESTHeart"
}

Par exemple, vous trouverez ci-dessous la requête complète que httpie envoie à RESTHeart lors de la publication d'un simple objet JSON sur le Collection "coll":

Accept: application/json

Vous pouvez également suivre les journaux de RESTHeart avec:

http -a 'admin:changeit' OPTIONS http://localhost:8080/db/coll

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Accept, Accept-Encoding, Authorization, Content-Length, Content-Type, Host, If-Match, Origin, X-Requested-With, User-Agent, No-Auth-Challenge
Access-Control-Allow-Methods: GET, PUT, POST, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ETag, Auth-Token, Auth-Token-Valid-Until, Auth-Token-Location, X-Powered-By
Connection: keep-alive
Content-Length: 0
Date: Tue, 12 Feb 2019 14:39:18 GMT
X-Powered-By: restheart.org


1 commentaires

avec httpie je n'ai aucun problème, uniquement lorsque j'essaye d'y publier depuis mon application



1
votes

Avec RESTHeart, vous n'avez pas besoin de l'en-tête key , qui n'est pas autorisé par CORS Access-Control-Allow-Headers . Supprimez donc le code de ligne suivant:

headers.append('key', 'demo');

key n'est requis qu'avec mrest.io . Sur le site Web de RESHeart, vous avez quelques exemples avec la note suivante:

Veuillez noter que les exemples utilisent le service cloud mrest.io pour RESTHeart. Il nécessite la clé api et a un format de représentation légèrement différent.


2 commentaires

Salut Andrea, merci pour la réponse, quand je supprime cette ligne, j'obtiens 401 (non autorisé). Est-ce que je manque une configuration quelque part?


Non autorisé car vous avez activé l'authentification, vous devez donc transmettre l'en-tête d'authentification de base. Consultez la documentation restheart.org/learn/clients-authentication avec Angular, je vous suggère de écrire et intercepteur pour ajouter l'en-tête Authorization à toutes les demandes angular.io/api/common/http/HttpInterceptor