簡體   English   中英

從 angularjs 調用 REST 服務時本地主機上的 CORS 問題

[英]CORS issue on localhost while calling REST service from angularjs

我正在學習 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) 中的響應,而 w3schools 的 REST 服務工作得很好。

{"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 控制台:通過從文件系統打開]

XMLHttpRequest 無法加載http://localhost:70/DocumentRESTService.svc/GetDocuments/ 請求的資源上不存在“Access-Control-Allow-Origin”標頭。 因此,不允許訪問源 'file://'。

  • [Chrome 控制台:使用括號托管]

XMLHttpRequest 無法加載http://localhost:70/DocumentRESTService.svc/GetDocuments/ 請求的資源上不存在“Access-Control-Allow-Origin”標頭。 因此,不允許訪問源“ http://127.0.0.1:55969 ”。

  • [火狐控制台:]

跨域請求被阻止:同源策略不允許讀取位於http://localhost:70/DocumentRESTService.svc/GetDocuments/的遠程資源。 這可以通過將資源移動到同一域或啟用 CORS 來解決。

這里的問題很少:

  1. 為什么 localhost 或 my machineName 被認為是跨域請求? 我在同一個域中,不是嗎?
  2. 是否需要在我的服務端進行任何更改才能啟用此行為? 如果是,WCF 服務在哪里?(基於我在此處閱讀的內容)
  3. 在這種情況下,JSONP 有用嗎? 如果是,我將如何使用它? 它可以處理需要自定義標頭的請求嗎?(不太確定它是什么,但是在重新搜索時發現了很多提到這一點的答案。閱讀鏈接會有所幫助。)

任何幫助或方向都會有所幫助。

PS:

  • IDE:括號,如果這很重要。
  • AngularJS v1.4.3
  • 我已經提到了各種涉及類似問題 (CORS) 的 stackoverflow 問題,其中涉及 $resource 、 $provider 、 $config ,還有一些與刪除某些標頭和添加標頭中的某個值有關。 我對此有點天真 - 對此的任何參考都會有所幫助。

由於模擬 Ionic 項目(在本地運行)與一些小型 Node.JS Web 服務(也在本地運行)的交互引起的 CORS 問題,我掙扎了太久。

看看簡短的簡單解決方法:Chrome 的插件 AllowControlAllowOrigin。

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

只需將單選按鈕從紅色切換到綠色,不再有阻塞的請求、錯誤或警告! 當然,這是一個臨時解決方案,當停止本地測試的時間到來時,您可能不得不將手放在請求標頭中。 與此同時,這是避免在那些煩人的反復問題上浪費時間的好方法。

我可以解決這個問題。 有幾種方法可以做到這一點 - 我正在記下我嘗試過的所有內容及其參考資料。

回答問題1。

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

正如@charlietfl 提到的,我在這里研究:不同的端口或子域也被瀏覽器考慮跨域。

回答問題2。

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

是的! 服務器端本身需要更改。 服務器應該響應請求

訪問控制允許來源:*

標題。 這里 * 可以替換為請求標頭本身或根據您的應用程序要求。 如果您使用 WCF REST 服務, 這里的優秀博客解釋了解決方法。 您需要向每個服務方法添加以下行(標題)以在您的服務方法中啟用 CORS。

WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Origin", "*"); WebOperationContext.Current.OutgoingResponse.Headers.Add(
"訪問控制允許方法", "POST"); WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Headers", "Content-Type, Accept");

這里的規范對於在服務器/客戶端上啟用 CORS 非常有幫助。

回答問題3。

JSONP 主要適用於 GET 請求,並不是最可取的用途,而是最推薦啟用 CORS。 (我沒有過多地探索這個領域,但這里的Wiki和 stackoverflow 文章非常具有描述性)。

除此之外,出於測試目的, 這里一個不錯的 chrome 擴展可能會有所幫助。 它可用於確保應用程序存在 CORS 問題。

如果您在訪問 localhost 機器中運行的 REST API 時遇到 AngularJS 應用程序中的 CORS 問題,請檢查以下內容:在您的服務器應用程序中添加 CORS 過濾器。 就我而言,我在 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() {
}

}

在 angularjs 代碼中,不要提供像 http:// localhost :8080/../ 這樣的 URL。 而不是 localhost 提供您的主機 IP 號。

它會正常工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM