2013-07-27 38 views
1

使用VS2012,框架4.5jQuery的AJAX之間ASPNET會議呼籲在CORS環境

我有一個簡單的Web應用程序,只需WebService.asmx文件。運行該項目公佈這些2個webMethods的,SetDataGetData,這裏的C#代碼:

[WebService(Namespace = "http://mydomain.com/")] 
[System.Web.Script.Services.ScriptService] 
public class WebService: System.Web.Services.WebService { 

    [WebMethod(EnableSession=true)] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public string SetData() { 
     HttpContext.Current.Session["someData"] = "xxxxxxxxx"; 
     return ""; 
    } 

    [WebMethod(EnableSession = true)] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public string GetData() { 
     if (HttpContext.Current.Session["someData"] == null) 
      return "Session NULL"; 
     else 
      return HttpContext.Current.Session["someData"].ToString(); 
    } 
} 

的Web.config被設置爲啓用CORS也aspNetCompatibilityEnabled啓用會話共享

<system.webServer> 
    <httpProtocol> 
    <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="null" /> 
     <add name="Access-Control-Allow-Headers" value="Content-Type" /> 
     <add name="Access-Control-Allow-Credentials" value="true" /> 
    </customHeaders> 
    </httpProtocol> 
</system.webServer> 

<system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 
</system.serviceModel> 

所以項目運行良好。現在我想從一個簡單的HTML頁面中使用這兩種方法(HTML是不是 ASPNET項目的一部分,僅僅是一個HTML文件...因此是CORS問題) 這裏是HTML代碼(省略HTML代碼爲了簡單,但它只是一個空白頁):

<script type="text/javascript"> 
    $(document).ready(function() { 
     //jQuery.support.cors = true; 
     $.ajax({ 
      type: "POST", 
      url: "http://localhost:62776/WebService.asmx/SetData", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      success: function(msg) { 
       alert('SetData OK'); 
       $.ajax({ 
        type: "POST", 
        url: "http://localhost:62776/WebService.asmx/GetData", 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        //async: true, -- makes no difference 
        //beforeSend: function(xhr){ 
        // xhr.withCredentials = true; 
        //}, 
        success: function(msg) { 
         alert('GetData: ' + msg.d); 
        }, 
        error: function(e){ 
         alert("GetData: Unavailable"); 
        } 
       }); 

      }, 
      error: function(e){ 
       alert("SetData: Unavailable"); 
      } 
     }); 
    }); 
</script> 

運行HTML頁面給我SetData OK然後GetData: Session NULL,但我想GetData: xxxxxx

所以我的問題是,我怎麼能訪問相同的Session Object在CORS呼叫之間?

我也嘗試啓用身份驗證,認爲ASPNET AUTH COOKIES會以某種方式保持AJAX調用之間正確的會話ID,但它不起作用。有一種使用SOAP信封來驗證每個AJAX調用併發送會話信息的可能方法,但這看起來過度。

+0

你看過IRequireSessionState嗎? http://msdn.microsoft.com/en-us/library/system.web.sessionstate.irequiressessionstate.aspx –

回答

1

您需要設置withCredentials這意味着客戶希望隱含的「東西」要發送的(包括餅乾):

http://brockallen.com/2012/12/15/cors-and-windows-authentication/

此外,因爲你需要「資格證書」被允許的話,服務器必須使用特定來源請求的Access-Control-Allow-Origin進行響應 - 它不能使用「*」。

+0

謝謝,已經嘗試過,並沒有工作。這裏的問題不是認證。我也知道你不能同時擁有Origin = *和Credentials。 Origin = *是CORS起源未知的唯一途徑,就像你發佈了一個開放的API,你不知道它將被訪問哪些域。 – Nick

+0

嗯,我唯一能想到的是發出cookie的請求還需要withCredentials。 –

1

你試過以下添加到您的web.config文件

<webServices> 
    <protocols> 
    <add name="HttpGet"/> 
    <add name="HttpPost"/> 
    </protocols> 
</webServices> 

或下面的代碼添加到您的Web方法:

[ScriptMethod(UseHttpGet = true)] 
public string HelloWorld() 
{ 
    return "Hello World"; 
} 

使用該打電話給你的服務(JavaScript的):

function SendAjaxRequest(url) { 

var xmlhttp = ""; 

if (window.XMLHttpRequest) { 
    xmlhttp = new XMLHttpRequest(); 
} else { 
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
} 

xmlhttp.open("GET", url, false); 
xmlhttp.onreadystatechange = function() { 
    //when response is ready 
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
     var rspText = xmlhttp.responseText; 
     if (rspText != undefined) { 
      // here is the response 
      var json = JSON.parse(rspText); 
     } 
    } 
} 

    xmlhttp.send(null); 
} 

如果您注意到返回的數據將被包裝在標籤中以將其刪除並僅獲取數據使用t他的功能:

function TrimXmlTag(start, responseText) { 

    var from = responseText.indexOf(start), 
     remaining = responseText.substring(from, responseText.length - 9); 

    return remaining; 
} 

,只是改變這一行:

var json = JSON.parse(TrimXmlTag("[",rspText)); 

希望它能幫助。

+0

好吧我試了兩個,沒有工作 – Nick

+0

@Nick:我有一個通過$ .ajax()調用asp.net webservice的相同問題嘗試將此添加到您的webservice方法HttpContext.Current.Response.AppendHeader(「Access-Control -Allow-Origin「,」*「); ...在搞砸之後,我剛剛使用XmlHttpRequest解決了這個問題 – maverickosama92

+0

@marverick我不認爲這個新的ActiveXObject(「Microsoft.XMLHTTP」);可以在Linux和Mac瀏覽器上工作。這個想法是通過任何平臺上的標準HTML5訪問web服務(Win/Mac/* nix/iOS/Android/BB10/etc) – Nick