web-dev-qa-db-fra.com

Problème de la SCRO sur localhost lors de l'appel REST service d'angularjs

J'apprends angularJS et j'essaie de le mettre en œuvre dans mon application.

J'ai un service RESTful WCF hébergé sur localhost IIS . Il possède une méthode GET définie pour extraire une liste de documents: http: // localhost: 70/DocumentRESTService.svc/GetDocuments/

Maintenant, j'essaie de consommer ce service dans mon application angulaire et d'afficher les données . Voici le code: HTML:

<html>
    <script src="../../dist/js/angular/angular.min.js"></script>
    <script src="../../assets/js/one.js"></script>
    <body ng-app="myoneapp" ng-controller="oneAppCtrl">
                {{"Hello" + "AngularJS"}}
        <hr>
        <h1> Response from my REST Service </h1>
        {{hashValue}}

        <hr>
        <h1> Response from w3school REST Service </h1>
        {{names}}


    </body>
</html>

JS:

angular.module('myoneapp', [])
    .controller('oneAppCtrl', function($scope,$http){
        $scope.documentValue = {};

        $http({method: 'GET',
                url: 'http://localhost:70/DocumentRESTService.svc/GetDocuments/',
                headers:
                        {
//                          'Access-Control-Allow-Origin': 'http://localhost'
                        }                   
               })
            .success(function(data){ alert('Success!'); $scope.documentValue=data;})
            .error(function(data){ alert('Error!'); $scope.documentValue=data; alert('Error!' + $scope.documentValue);})
            .catch(function(data){ alert('Catch!'); $scope.documentValue= data;});

        $http.get("http://www.w3schools.com/angular/customers.php")
            .success(function(response) {$scope.names = response.records;});            
});

Le comportement étrange est que ce code fonctionne parfaitement dans IE11, alors qu'il ne tourne pas dans Chrome/Firefox.

Voici la réponse chromée: (pour mon service REST), alors que le service REST de w3schools a fonctionné correctement.

{"data": null, "status": 0, "config": {"method": "GET", "transformRequest": [null], "transformResponse": [null], "url": " http : // localhost: 70/DocumentRESTService.svc/GetDocuments/ "," en-têtes ": {" Accept ":" application/json, text/plain, / "}," statusText " : ""}

La console a affiché le message d'erreur suivant.

  • [Console Chrome: en ouvrant à partir de système de fichiers

XMLHttpRequest ne peut pas charger http: // localhost: 70/DocumentRESTService.svc/GetDocuments/ . Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée. Le fichier d'origine: // 'n'est donc pas autorisé.

  • [Console Chrome: hébergé à l'aide de Brackets]

XMLHttpRequest ne peut pas charger http: // localhost: 70/DocumentRESTService.svc/GetDocuments/ . Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée. Origin ' http://127.0.0.1:55969 ' n'est donc pas autorisé à accéder.

  • [Console Firefox:]

Demande d'origine croisée bloquée: la règle d'origine identique interdit la lecture de la ressource distante à http: // localhost: 70/DocumentRESTService.svc/GetDocuments/ . Cela peut être corrigé en déplaçant la ressource dans le même domaine ou en activant CORS.

La question ici sont peu:

  1. Pourquoi localhost ou mon nom_ordinateur est-il considéré comme une requête interdomaine? Je suis dans le même domaine, n'est-ce pas?
  2. Y at-il des changements à faire à mon service pour activer ce comportement? Si oui, où dans le service WCF? (Basé sur quelque chose que j'ai lu ici )
  3. un JSONP être utile dans ce cas? Si oui, comment pourrais-je l'utiliser? Cela ne fonctionnerait-il pas avec les demandes nécessitant des en-têtes personnalisés? (PAS vraiment sûr de ce que c'est, mais en cherchant dans la liste, on trouve beaucoup de réponses à ce sujet. lire des liens sera utile.)

Toute aide ou direction sera utile.

P.S:

  • IDE: Supports , si cela compte.
  • AngularJS v1.4.3
  • J'ai fait référence à diverses questions de stackoverflow faisant référence à un problème similaire (CORS), qui impliquait $ ressource, $ fournisseur, $ config. Certaines concernaient également la suppression de certains en-têtes et l'ajout de valeurs à l'une des en-têtes. Je suis un peu naïf à cela - toute référence à cela sera utile.
8
Bhramar

Je pourrais résoudre ce problème . Quelques façons de le faire - je note tout ce que j'ai essayé et leurs références.

Répondre à Ques1. 

'Why is localhost or my machineName considered to be a cross-domain request?'

comme @charlietfl mentionné et i Researched here : un autre port ou sous-domaine est également à considérer entre domaines par navigateur.

Répondre à Ques2. 

'Are there any changes required to do at my service end to enable this behavior?'

OUI! le changement est requis sur le serveur lui-même. Le serveur doit répondre à la demande avec 

Access-Control-Allow-Origin: *

entête. Ici, le * peut être remplacé par l'en-tête de requête lui-même ou selon vos besoins. Excellent blog ici expliquant la solution de contournement si vous utilisez le service WCF REST. Vous devez ajouter la ligne suivante (en-têtes) à chaque méthode de service pour activer CORS dans vos méthodes de service.

WebOperationContext.Current.OutgoingResponse.Headers.Add (
"Accès-Contrôle-Autoriser-Origine", "*"); WebOperationContext.Current.OutgoingResponse.Headers.Add (
"Accès-Contrôle-Autoriser-Méthodes", "POST"); WebOperationContext.Current.OutgoingResponse.Headers.Add (
"Accès-Contrôle-Autoriser-En-têtes", "Type de contenu, Accepter");

Une spécification ici est très utile pour activer CORS sur le serveur/client.

Réponse à Ques3.

JSONP fonctionne principalement pour les requêtes GET et ne constitue pas une utilisation recommandée. Il est plutôt recommandé d'activer CORS. (Je n'ai pas beaucoup exploré ce domaine mais Wiki & article de stackoverflow ici était très descriptif). 

En dehors de cela, à des fins de test, une extension Nice chrome ici peut être utile. Il peut être utilisé pour s’assurer que l’application a des problèmes CORS.

6
Bhramar

Je me suis débattu trop longtemps avec les problèmes liés à la CORS causés par l’interaction d’un projet ionique émulé (exécuté localement) avec des petits services Web Node.JS (également exécutés localement).

Voici la solution de contournement simple et rapide: le plugin AllowControlAllowOrigin de Chrome.

https://chrome.google.com/webstore/search/cross%20origin?utm_source=chrome-ntp-icon&_category=extensions

Il suffit de passer le bouton radio du rouge au vert et plus aucune demande bloquée, erreur ou avertissement! Bien sûr, il s’agit d’une solution temporaire et il se peut que vous deviez mettre vos mains dans les en-têtes de votre demande lorsque le moment d’arrêter les tests locaux viendra. En attendant, c'est un excellent moyen d'éviter de perdre du temps sur ces problèmes récurrents et inquiétants.

4
Sendil.J

Si vous rencontrez un problème CORS dans les applications AngularJS lors de l'accès à l'API REST s'exécutant sur la machine localhost, vérifiez les points suivants: Ajoutez le filtre CORS dans votre application serveur. Dans mon cas, j'ai ajouté le code ci-dessous dans l'application Spring.

import Java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class SimpleCORSFilter implements Filter {

private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

public SimpleCORSFilter() {
    log.info("SimpleCORSFilter init");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}

}

Dans le code angularjs, ne donnez pas une URL telle que http: // localhost : 8080 /../. Au lieu de localhost, donnez le numéro IP de votre hôte.

Ça fonctionnera correctement

1
Suresh Selvaraj

Mon ami . Seulement tapez 

/DocumentRESTService.svc/GetDocuments
0
Julian Porras