2014-07-11 10 views
2

我和我的工作夥伴花了很多時間找到答案,所以我想我應該分享這個自我回答的問題。如何啓用會話ASP.NET Web服務與不同域中的ajax客戶端一起工作?

我有一個Web服務(ASP.NET 4.5),需要使用會話狀態的方法。爲了存檔,我用EnableSession = true修飾了方法。這是MS建議在this article中做的事情(參見最後的「代碼塊A」)。

爲了讓Web服務能夠重新使用會話,它需要找到一個帶有會話ID的cookie。在第一次調用該方法時,該cookie在服務器端由Web服務器本身創建和設置。爲了在每次通話時重新發送該cookie,MS建議使用一個「cookie容器」,該cookie容器被分配給Web服務代理,保存在通話間並在每次通話時重複使用。 (請參閱最後的「代碼塊B」)。

只要您計劃從服務器端調用Web服務,它就會很好用。我需要使用jQuery ajax JSON Post調用從客戶端調用它(請參閱末尾的「代碼塊C」)。這段代碼很好用。事實上,具有會話ID的cookie會自動傳遞給Web服務。只要客戶端和Web服務位於同一個域中,就不需要Cookie罐。

如果客戶端與web服務(domainb.com)位於不同的域(domaina.com)中,則帶有會話標識的cookie根本不會傳遞。因此,每個對Web服務的調用都被認爲是第一個。

我在web配置中定義了以下頭文件以允許跨域調用。

<add name="Access-Control-Allow-Origin" value="*" /> 
<add name="Access-Control-Allow-Headers" value="Content-Type" /> 

那麼,什麼是缺失?

代碼塊答:Web服務與裝飾方法

public class Util: WebService { 
    [ WebMethod(EnableSession=true)] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public int SessionHitCounter() { 
     if (Session["HitCounter"] == null) { 
      Session["HitCounter"] = 1; 
     } 
     else { 
      Session["HitCounter"] = ((int) Session["HitCounter"]) + 1; 
      } 
     return ((int) Session["HitCounter"]); 
    } 
} 

代碼塊B:服務器端餅乾罐解決方案

<script runat="server"> 

    void EnterBtn_Click(Object Src, EventArgs E) 
{ 
    // Create a new instance of a proxy class for your XML Web service. 
    ServerUsage su = new ServerUsage(); 
     CookieContainer cookieJar; 

    // Check to see if the cookies have already been saved for this session. 
    if (Session["CookieJar"] == null) 
    cookieJar= new CookieContainer(); 
     else 
    cookieJar = (CookieContainer) Session["CookieJar"]; 

    // Assign the CookieContainer to the proxy class. 
    su.CookieContainer = cookieJar; 

    // Invoke an XML Web service method that uses session state and thus cookies. 
    int count = su.PerSessionServiceUsage();   

    // Store the cookies received in the session state for future retrieval by this session. 
    Session["CookieJar"] = cookieJar; 

     // Populate the text box with the results from the call to the XML Web service method. 
     SessionCount.Text = count.ToString(); 
    } 

</script> 

代碼塊C:AJAX調用

  $.ajax({ 
       type: "POST", 
       url: web_services_url + "/SessionHitCounter", 
       data: "{}", 
       contentType: "application/json; charset=utf-8", 
       dataType: "json", 
       success: function (msg) { 
        alert(msg.d); 
       } 
      }); 

回答

3

後幾小時的思考和谷歌搜索我的伴侶發現我們失蹤

  • 一個額外的標題(「接入控制允許憑證」)
  • 更改「*」的「訪問控制允許來源」到被調用Web服務
  • 特定領域在Ajax調用增加一個額外的參數(withCredentials)

這些都是需要啓用CORS

<add name="Access-Control-Allow-Origin" value="http://localhost:53710" /> 
<add name="Access-Control-Allow-Headers" value="Content-Type" /> 
<add name="Access-Control-Allow-Credentials" value="true" /> 

頁眉這是帶額外參數的ajax呼叫

$.ajax({ 
    type: "POST", 
    xhrFields: { withCredentials: true }, 
    url: web_services_url + "/SessionHitCounter", 
    data: "{}", 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 
    success: function (msg) { 
     alert(msg.d); 
    } 
}); 
相關問題