2013-10-31 154 views
1

我想做一個ajax調用(使用IE 10)返回json(而不是jsonp)的頁面,但我不斷收到「401 - 未經授權:訪問由於無效憑據而被拒絕」。該站點在IIS中設置爲使用「Windows身份驗證」,但是,如果我更改站點以啓用匿名身份驗證,則該調用將起作用。以下是我用來打電話的代碼。我在打電話時錯過了什麼,或者我需要在網絡服務器上更改什麼? Windows身份驗證目前已設置爲在Windows身份驗證上使用NTLM身份驗證。ajax呼叫轉移安全

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title> 
    <script src="scripts/jquery-2.0.3.min.js"></script> 
    <script src="scripts/base64.js"></script> 
    <script type="text/javascript"> 
     function QueryMyData() { 
      var postUrl = 'http://mydevpage/storage.ashx'; 
      var data = 'AssetNumber=102405'; 
      $.support.cors = true; 
      $.ajax({ 
       type: "POST", 
       url: postUrl, 
       data: data, 
       dataType: 'json', 
       crossDomain: true, 
       cache: false, 
       username: "mydomain.net\\myuser", 
       password: "password", 
       beforeSend: function (xhr) { 
        xhr.withCredentials = true; 

       }, 
       success: function (result) { 
        if (result) { 
         if (result.error) 
          alert(result.error); 
         else 
          alert(result.id); 
        } 
       }, 
       error: function (xhr, ajaxOptions, thrownError) { 
        alert('Unknow Error:' + thrownError + ajaxOptions + xhr.status + " " + xhr.statusText); 
       } 
      }); 
     } 
     QueryMyData(); 
    </script> 
</head> 
<body> 
</body> 
</html> 
+0

好一件事是,' 「mydomain.net \ myuser的」'可能是錯誤的;那可能應該是''mydomain.net \\ myuser「'。 – Pointy

+2

'username =「mydomain.net \ myuser」,'和下面的行是無效的,'不需要crossDomain','$ .support.cors'不需要,scripts/jquery-2.0.3.min。 js在IE8中不起作用,而CORS在沒有插件的情況下無法在jQuery中使用jQuery。這裏有很多錯誤。 –

+2

另一個是'username:「...」,'應該是,不是'username =「...」,「 –

回答

1

我找到了我的問題的解決方案。雖然我無法獲得ajax請求來處理在另一個域上打開頁面的安全性,但我確實找到了一種方法來完成此操作。我最終創建了一個ProxyHandler.ashx頁面,並使用WebClient在請求上設置權限。

html頁面

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> 
    <script type="text/javascript"> 
     function QueryMyData() { 
      var postUrl = './ProxyHandler.ashx?http://mydevpage/storage.ashx'; 
      var data = 'AssetNumber=102405'; 
      $.support.cors = true; 
      $.ajax({ 
       type: "POST", 
       url: postUrl, 
       data: data, 
       dataType: 'json', 
       cache: false, 
       success: function (result) { 
        if (result) { 
         if (result.error) 
          alert(result.error); 
         else 
          alert(result.id); 
        } 
       }, 
       error: function (xhr, ajaxOptions, thrownError) { 
        alert('Unknow Error:' + thrownError + ajaxOptions + xhr.status + " " + xhr.statusText); 
       } 
      }); 
     } 
     QueryMyData(); 
    </script> 
</head> 
<body> 
</body> 
</html> 

這裏是代理頁面(ProxyHandler.ashx)

public class ProxyHandler : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     string username = "svcMyServiceAccount"; 
     string password = "password"; 
     try 
     { 
      string uri = context.Request.RawUrl.Substring(context.Request.RawUrl.IndexOf("?") + 1); 

      if (uri.StartsWith("ping")) 
      { 
       context.Response.Write("<html><body>Hello ProxyHandler</body></html>"); 
       return; 
      } 

      context.Response.ContentType = "text/plain"; 

      byte[] bytes = new byte[context.Request.InputStream.Length]; 
      context.Request.InputStream.Read(bytes, 0, (int)context.Request.InputStream.Length); 
      var data = System.Text.Encoding.UTF8.GetString(bytes); 

      using (System.Net.WebClient wc = new System.Net.WebClient()) 
      { 
       wc.Headers["Content-Type"] = "application/x-www-form-urlencoded"; 
       //this is the magic of getting auth passed. See post http://stackoverflow.com/questions/1680718/domain-credentials-for-a-webclient-class-dont-work 
       wc.Credentials = CreateCredientialCached(uri, username, password, "mydomain"); 
       var response = wc.UploadString(new Uri(uri, UriKind.Absolute), "POST", data); 
       context.Response.Write(response); //already in the JSON Reponse class format 
      } 
     } 
     catch (Exception e) 
     { 
      context.Response.Write(GetJSON(string.Empty, e)); 
     } 
    } 

    private CredentialCache CreateCredientialCached(string uri, string userName, string userPassword, string domain) 
    { 
     CredentialCache cc = new CredentialCache(); 
     cc.Add(new Uri(uri), "NTLM", new NetworkCredential(userName, userPassword, domain)); 
     return cc; 
    } 

    private string GetJSON(string id, Exception error) 
    { 
     var json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(new Response() { id = id, error = error != null ? error.ToString() : string.Empty }); 
     return json; 
    } 

    // Necessary for IHttpHandler implementation 
    public bool IsReusable 
    { 
     get { return false; } 
    } 

    private class Response 
    { 
     public string id { get; set; } 
     public string error { get; set; } 
    }; 
} 
+0

儘管我的情況並不完全相同,但您的回答確實讓我使用WebClient來解決與cors相關的ajax問題。 –