1

好的,所以由于某种原因,即使服务器返回 200 和有效的 json,我的 ajax 调用仍然失败。这是ajax调用:

        $.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);
            }
        });

错误函数显示空白。类型说“错误”,但之后什么都没有。我试图弄清楚为什么会发生这种情况???

通过 fiddler 验证,这是从服务器返回的 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。

更新:在 ajax 调用之前添加以下内容使其可以在 IE 中工作,但不能在 chrome 中工作:

$.support.cors = true;
4

2 回答 2

1

当我从文件系统上的 html 页面测试对 Web 服务器的 ajax 调用时,我遇到了类似的问题。我想这算作“跨域”ajax。我有完全相同的症状。Wireshark 显示来自 Web 服务器的非常好的响应,但我收到了一个没有数据的错误事件。

一旦我将 HTML 文件移动到 Web 服务器 - 这样我的页面(ajax 客户端)和 ajax Web 服务就在同一个域中,它就开始工作了。

但是,如果提交 ajax 的网页是从那里提供的,http://localhost:10590/那么这不适用,并且您遇到了不同的问题。

于 2012-12-15T01:30:10.050 回答
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;
        }
    }
}
于 2013-02-04T20:53:39.357 回答