2011-06-09 94 views
1

我編寫了一個返回JSON響應的WCF服務。然後我創建了一個帶有JavaScript代碼的HTML頁面來測試函數。當我將服務發佈到臨時環境(使用SSL模擬生產環境)時,我不得不更新服務的web.config文件以通過HTTPS進行工作。當我直接瀏覽到.svc端點(服務頁面同時顯示在http和https中)以及當我在瀏覽器中調用服務時(我被提示下載JSON響應)時,所有這一切似乎都可以,但是當我將測試頁更改爲指向https版本,我得到一個'訪問被拒絕'的錯誤。通過HTTPS從Javascript調用WCF服務導致拒絕訪問

這裏是我的配置文件的servicemodel部分代碼:

<system.serviceModel> 


    <services> 

     <service name="Services.PromotionCodeGeneration" behaviorConfiguration="md"> 
     <endpoint address="" binding="webHttpBinding" contract="Services.IPromotionCodeGeneration" behaviorConfiguration="webHttp" bindingConfiguration="webBindingSecure"/> 
     <endpoint address="" binding="webHttpBinding" contract="Services.IPromotionCodeGeneration" behaviorConfiguration="webHttp" bindingConfiguration="webBinding"/> 
     <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /> 

     </service> 

    </services> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior name="md"> 
      <serviceMetadata httpsGetEnabled="true" /> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="webHttp"> 
      <webHttp /> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 



    <bindings> 

     <webHttpBinding> 

     <binding name="webBindingSecure"> 

      <security mode="Transport"/> 

     </binding> 

     <binding name="webBinding"> 

      <security mode="None"></security> 

     </binding> 

    </webHttpBinding> 



    </bindings> 

    </system.serviceModel> 

這裏是我的測試頁的代碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head> 
    <title></title> 
<script> 
    function api_test() { 

     var url = "https://test.mydomain.com/Services/PromotionCodeGeneration.svc/contest/[email protected]"; 

     var client = new XMLHttpRequest(); 
     client.open("GET", url, false); 
     client.setRequestHeader("Authentication-Key", "LK589-JIJO-SHG9-0987-65TG-HJKU-Y$GH"); 
     client.send(); 
     var responseText = client.responseText; 

     var result = JSON.parse(responseText); 


     document.writeln("Id: " + result.Id + "<br/>"); 
     document.writeln("Code: " + result.Code + "<br/>"); 
     var expiryDate = ""; 
     if (result.Expires != null){expiryDate = result.Expires;} 
     document.writeln("Expires: " + expiryDate + "<br/>"); 
     document.writeln("Status: " + result.Status + "<br/>"); 
    } 
</script> 
</head> 
<body onload="api_test();"> 

</body> 
</html> 

我一直在研究這個問題2天。我發現很多人說你不能跨域使用'XMLHttpRequest'方法,但它可以爲我找到基本的http,所以我覺得很難相信。我也嘗試了許多不同的servicemodel配置建議,但是沒有一個用於https通信。有沒有人看到任何在我的配置或調用頁面導致通過https訪問「拒絕」的任何東西?

任何幫助,將不勝感激。

+0

多個域的提及讓我覺得有沒有託管在同一個域?那是對的嗎?它不是你可能想要看看周圍的jsonp - http://stackoverflow.com/questions/2055186/json-and-xmlhttprequest – 2011-06-09 22:45:53

回答

2

HTML頁面和服務是否符合Same Origin Policy

  • 域名必須相同,包括子域(所以你不能,例如,加載在test2.example.com在頁面上test1.example.com託管的文件)。

  • 協議(例如httphttps)必須相同。

  • 端口必須相同(例如,您無法從example.com上的頁面加載example.com:8080處的文件)。

所有的AJAX請求需要滿足此政策 - 否則,作爲@Mike米勒建議,你可能需要看看JSONP

+0

感謝您的建議閱讀 - 我會看看。該服務最終將託管在我們的一個公司網站上(希望是我們的SSL域名之一),並通過在Facebook上託管的Flash應用程序訪問。目前,我在本地機器上託管測試頁面並在舞臺服務器上訪問該服務。它可以正常工作在http上,但當我嘗試通過https訪問它時,出現訪問被拒絕錯誤。如果它是不同的域名,爲什麼它會通過http工作? – John 2011-06-10 00:54:46

+0

看起來你們對跨域問題是正確的 - 它一定是通過http從我的本地主機上運行的,因爲我和web服務器位於同一網絡域,即使它不出現在本地主機url中。然後將主機鏈接到https違反同源策略。當我將測試文件移動到Web服務器,並通過https查看時,對WCF服務的調用成功。 – John 2011-06-10 15:17:54

+0

起初,我認爲這將是Facebook上的最終Flash客戶端的問題,但事實證明,Adobe已經提出了一個策略文件概念,在該策略文件中將xml策略文件放置在允許通信的服務目錄中。我無法弄清楚如何在此評論中發佈鏈接(殺死添加功能),但如果谷歌的「Adobe跨域策略」,第一個結果應該是Adobe頁面的鏈接,描述策略文件概念及其規範。 – John 2011-06-10 15:26:40

相關問題