2012-12-15 39 views
1

好吧,所以出於某種原因,即使服務器返回200有效的json,我的ajax調用仍會失敗。這裏是阿賈克斯調用:服務器返回有效的json和200,但錯誤功能正在拋出

 $.ajax(
     { 
      cache: false, 
      type: "GET", 
      url: "http://localhost:10590/api/entry", 
      dataType: "application/json; charset=utf-8", 
      success: function (result) { 
       alert('HIT'); 
      }, 
      error: function (request, type, errorThrown) { 
       alert('Fail' + type + ':' + errorThrown); 
      } 
     }); 

錯誤函數顯示空白。類型說「錯誤」,但之後沒有。我想弄清楚爲什麼會發生這種情況?

通過小提琴手經查實,這是從服務器返回的JSON字符串:

{ 
    "EntryId":0, 
    "EntryDate":"2012-12-14T18:10:48.2275967-07:00", 
    "BodyWeight":207.00, 
    "Bmi":0.0, 
    "Fat":0.0, 
    "Visceral":0.0, 
    "MuscleMass":0.0 
} 

http://jsonlint.com/同意這是有效的JSON。

UPDATE: 添加以下的AJAX調用將會在IE瀏覽器而不是鉻工作之前:

$.support.cors = true; 
+0

我很確定'dataType'應該只是「json」。這不是一個MIME類型,也不是一個Content-Type頭。這只是提示jQuery如何解釋響應。另外,爲什麼不只是使用'/ api/entry'來保存你的URL,並且避免需要'cors' –

+0

??因爲那會使它成爲一個相對的地址。頁面和服務是兩個不同的網站。我只是碰巧託管了他們兩個。 – Sinaesthetic

回答

0

我最終使用的解決方案是從服務器請求'jsonp'。爲了讓我的服務器返回jsonp,我必須創建一個自定義格式化程序。我很難找到一個格式化程序,因爲每篇文章都提到了Thinktecture,它不會爲我編譯。所以這裏是我結束了:

using System; 
using System.IO; 
using System.Net; 
using System.Net.Http.Formatting; 
using System.Net.Http.Headers; 
using System.Threading.Tasks; 
using System.Web; 
using System.Net.Http; 
using Newtonsoft.Json.Converters; 

namespace MyDomain.Common.Web.CustomFormatters 
{ 

    /// <summary> 
    /// Handles JsonP requests when requests are fired with text/javascript 
    /// </summary> 
    public class JsonpFormatter : JsonMediaTypeFormatter 
    { 

     public JsonpFormatter() 
     { 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript")); 

      JsonpParameterName = "callback"; 
     } 

     /// <summary> 
     /// Name of the query string parameter to look for 
     /// the jsonp function name 
     /// </summary> 
     public string JsonpParameterName { get; set; } 

     /// <summary> 
     /// Captured name of the Jsonp function that the JSON call 
     /// is wrapped in. Set in GetPerRequestFormatter Instance 
     /// </summary> 
     private string JsonpCallbackFunction; 


     public override bool CanWriteType(Type type) 
     { 
      return true; 
     } 

     /// <summary> 
     /// Override this method to capture the Request object 
     /// </summary> 
     /// <param name="type"></param> 
     /// <param name="request"></param> 
     /// <param name="mediaType"></param> 
     /// <returns></returns> 
     public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType) 
     { 
      var formatter = new JsonpFormatter() 
      { 
       JsonpCallbackFunction = GetJsonCallbackFunction(request) 
      }; 

      // this doesn't work unfortunately 
      //formatter.SerializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings; 

      // You have to reapply any JSON.NET default serializer Customizations here  
      formatter.SerializerSettings.Converters.Add(new StringEnumConverter()); 
      formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; 

      return formatter; 
     } 


     public override Task WriteToStreamAsync(Type type, object value, 
             Stream stream, 
             HttpContent content, 
             TransportContext transportContext) 
     { 
      if (string.IsNullOrEmpty(JsonpCallbackFunction)) 
       return base.WriteToStreamAsync(type, value, stream, content, transportContext); 

      StreamWriter writer = null; 

      // write the pre-amble 
      try 
      { 
       writer = new StreamWriter(stream); 
       writer.Write(JsonpCallbackFunction + "("); 
       writer.Flush(); 
      } 
      catch (Exception ex) 
      { 
       try 
       { 
        if (writer != null) 
         writer.Dispose(); 
       } 
       catch { } 

       var tcs = new TaskCompletionSource<object>(); 
       tcs.SetException(ex); 
       return tcs.Task; 
      } 

      return base.WriteToStreamAsync(type, value, stream, content, transportContext) 
         .ContinueWith(innerTask => 
         { 
          if (innerTask.Status == TaskStatus.RanToCompletion) 
          { 
           writer.Write(")"); 
           writer.Flush(); 
          } 

         }, TaskContinuationOptions.ExecuteSynchronously) 
         .ContinueWith(innerTask => 
         { 
          writer.Dispose(); 
          return innerTask; 

         }, TaskContinuationOptions.ExecuteSynchronously) 
         .Unwrap(); 
     } 

     /// <summary> 
     /// Retrieves the Jsonp Callback function 
     /// from the query string 
     /// </summary> 
     /// <returns></returns> 
     private string GetJsonCallbackFunction(HttpRequestMessage request) 
     { 
      if (request.Method != HttpMethod.Get) 
       return null; 

      var query = HttpUtility.ParseQueryString(request.RequestUri.Query); 
      var queryVal = query[this.JsonpParameterName]; 

      if (string.IsNullOrEmpty(queryVal)) 
       return null; 

      return queryVal; 
     } 
    } 
} 
1

我有,當我AJAX調用Web服務器從測試類似的問題文件系統上的html頁面。我想這就是'跨域'ajax。我有完全相同的症狀。 Wireshark顯示來自Web服務器的完美響應,但是我得到了一個沒有數據的錯誤事件。

一旦我將HTML文件移動到Web服務器 - 這樣我的頁面(ajax客戶端)和ajax Web服務在同一個域中,它就開始工作了。

但是,如果提交ajax的網頁是由http://localhost:10590/提供的,那麼這不適用,並且您有不同的問題。

+0

它被託管在IIS Express中。該頁面位於端口9119,服務位於端口10590上 – Sinaesthetic

+0

您可以通過10590上的服務提供測試html頁面的任何方式?只是爲了看看它是否能更好地工作並診斷這是否是跨域問題? –

+0

實際上,我只是從IE瀏覽器而不是Chrome瀏覽器中運行頁面,現在我在js錯誤「No Transport」中收到了一些信息 - 聽起來像跨域問題,不是嗎? – Sinaesthetic

相關問題