web-dev-qa-db-ja.com

RESTサービスのanglejsからの呼び出し中のローカルホストでのCORSの問題

AngularJSを学び、それをアプリケーションに実装しようとしています。

Localhost IISでホストされているRESTful WCFサービスがあります。ドキュメントのリストを取得するために定義されたGETメソッドがあります: http:// localhost:70/DocumentRESTService.svc/GetDocuments /

今、私はangularアプリでこのサービスを利用してデータを表示しようとしています。以下はコードです: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;});            
});

奇妙な動作は、このコードがIE11で完全に機能するのに対して、Chrome/Firefoxでは実行されないことです。

以下はchrome:(for my REST service)の応答です。一方、REST w3schoolsのサービスは問題なく動作しました。

{"data":null、 "status":0、 "config":{"method": "GET"、 "transformRequest":[null]、 "transformResponse":[null]、 "url": " http:// localhost:70/DocumentRESTService.svc/GetDocuments / "、" headers ":{" Accept ":" application/json、text/plain、/ "}}、" statusText ":" "}

次のエラーメッセージがコンソールに表示されました。

  • [Chromeコンソール:filesystemから開く]

XMLHttpRequestをロードできません http:// localhost:70/DocumentRESTService.svc/GetDocuments / 。要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、Origin 'file://'はアクセスを許可されません。

  • [Chromeコンソール:Bracketsを使用してホスト]

XMLHttpRequestをロードできません http:// localhost:70/DocumentRESTService.svc/GetDocuments / 。要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。オリジン ' http://127.0.0.1:55969 'はアクセスが許可されていません。

  • [Firefoxコンソール:]

Cross-Origin Request Blocked:Same Origin Policyは、 http:// localhost:70/DocumentRESTService.svc/GetDocuments / でリモートリソースの読み取りを許可しません。これは、リソースを同じドメインに移動するか、CORSを有効にすることで修正できます。

ここでの質問はほとんどありません:

  1. LocalhostまたはmachineNameがクロスドメインリクエストと見なされるのはなぜですか?私は同じドメインにいますよね?
  2. この動作を有効にするためにサービス終了時に行う必要がある変更はありますか?はいの場合、WCFサービスのどこに?(読んだものに基づいて ここ
  3. jSONPはこの場合に便利ですか?はいの場合、どのように使用しますか?カスタムヘッダーを必要とするリクエストで動作しますか?(それが何であるかは確かではありませんが、再考中にこれに言及する多くの答えが見つかりました。リンクを読むことは役立ちます。)

どんな助けや指示も役立ちます。

追伸:

  • IDE: ブラケット 、それが重要な場合。
  • AngularJS v1.4.3
  • $ resource、$ provider、$ configを含む同様の問題(CORS)を参照するさまざまなstackoverflowの質問を参照しました。また、ヘッダーの削除とヘッダーの値1の追加に関連するものもあります。私はこれに少し素朴です-これへの参照は役に立ちます。
10
Bhramar

この問題を解決できました。そのためのいくつかの方法-私が試したすべてのこととその参照を書き留めています。

Ques1への回答。

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

@charlietflが言及し、i Researched here :別のポートまたはサブドメインもブラウザごとにクロスドメインと見なされます。

Ques2への回答。

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

はい!サーバー側で変更が必要です。サーバーはリクエストに応答する必要があります

Access-Control-Allow-Origin:*

ヘッダ。ここで、*は要求ヘッダー自体に置き換えることも、アプリケーションの要件に従って置き換えることもできます。優れたブログ こちら WCFを使用している場合の回避策の説明RESTサービス。各サービスメソッドに次の行(ヘッダー)を追加して、CORSを有効にする必要があります。サービス方法。

WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Origin"、 "*"); WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Methods"、 "POST"); WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Headers"、 "Content-Type、Accept");

仕様 here は、サーバー/クライアントでCORSを有効にするのに非常に役立ちます。

Ques3への回答。

JSONPは主にGETリクエストで機能し、使用することはお勧めできません。むしろ、CORSを有効にすることをお勧めします。 (この領域についてはあまり調べていませんが、 Wiki &stackoverflow article here は非常に説明的でした)。

それとは別に、テストの目的で、Nice chrome extension here が役立ちます。アプリケーションにCORSの問題があることを確認するために使用できます。

7
Bhramar

エミュレートされたIonicプロジェクト(ローカルで実行中)といくつかの小さなNode.JS Webサービス(ローカルで実行中)の相互作用に起因するCORSの問題に長い間苦労しました。

短い簡単な回避策を見てください:ChromeのプラグインAllowControlAllowOrigin。

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

ラジオボタンを赤から緑に切り替えるだけで、ブロックされたリクエスト、エラー、警告はなくなります!もちろん、これは一時的な解決策であり、ローカルテストを停止するときが来たら、リクエストヘッダーに手を入れる必要があります。それまでの間、それは厄介な再発性の問題で時間を失うことを避けるための素晴らしい方法です。

4
Sendil.J

REST localhostマシンで実行中のAPIにアクセスしているときにAngularJSアプリケーションでCORSの問題に直面している場合、サーバーアプリケーションにCORSフィルターを追加します。私の場合、次のコードを追加しました春のアプリケーション

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() {
}

}

Angularjsコードでは、http:// localhost:8080 /../のようなURLを指定しないでください。 localhostの代わりに、ホストIP番号を指定します。

正常に動作します

2
Suresh Selvaraj

私の友人。タイプのみ

/DocumentRESTService.svc/GetDocuments
0
Julian Porras