将数据发布到不同的域时收到错误

时间:2015-05-06 10:07:14

标签: jquery ajax cross-domain cors web-site-project

我正在开发一个网站,我需要在其中发布数据以创建记录。我的服务器端代码位于不同的域上。我需要从该域调用该方法。我调用该方法的ajax代码是as-

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">        
<head runat="server">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 

<script type="text/javascript">
    $(document).ready(function () {
            $('#create').click(function (e) {    
                var url = 'http://abc.in/api/api/Patient/Create';
                $.ajax({
                    url: url,
                    crossDomain: true,
                    contentType: "application/json",
                    dataType: "json",                         
                    data: JSON.stringify(getData()),
                    type: 'POST',                    
                    success: function (result) {                       
                    },
                    error: function (result) {
                    }
                });
            });
     });    
    </script>
</head>

我在Global.asax中的服务器端代码是 -

 public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapHttpRoute(
            name: "Create",
            routeTemplate: "api/Patient/Create",
            defaults: new { controller = "Patient", action = "Create" }
        );

            routes.MapHttpRoute(
            name: "Update",
            routeTemplate: "api/Patient/Update",
            defaults: new { controller = "Patient", action = "Update" }
        );    
            routes.MapHttpRoute(
            name: "Get",
            routeTemplate: "api/Patient/Get/{id}",
            defaults: new { controller = "Patient", action = "Get" }
        );

           routes.MapHttpRoute(
           name: "GetUploadDocumentListByPatient",
           routeTemplate: "api/UploadFile/GetUploadDocumentListByPatient/{id}",
           defaults: new { controller = "UploadFile", action = "GetUploadDocumentListByPatient" }
       );    
            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new {controller="Patient", action = "GetTest", id = RouteParameter.Optional }
            );
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);
            GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());    
            var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
        }

我的CorsHandler如下 -

public class CorsHandler : DelegatingHandler
    {
        private const string Origin = "Origin";    
        private const string AccessControlRequestMethod = "Access-Control-Request-Method";    
        private const string AccessControlRequestHeaders = "Access-Control-Request-Headers";    
        private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";    
        private const string AccessControlAllowMethods = "Access-Control-Allow-Methods";    
        private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";   

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);    
            bool isPreflightRequest = request.Method == HttpMethod.Options;    
            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    var response = new HttpResponseMessage(HttpStatusCode.OK);    
                    response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());      
                    string accessControlRequestMethod =                            request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();

                    if (accessControlRequestMethod != null)
                    {
                        response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                    }    
                    try
                    {
                        IEnumerable<string> headers = request.Headers.GetValues(AccessControlRequestHeaders);
                        ;    
                        if (headers != null)
                        {
                            string requestedHeaders = string.Join(", ",                                    request.Headers.GetValues(AccessControlRequestHeaders));    
                            if (!string.IsNullOrEmpty(requestedHeaders))
                            {                                    response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                            }
                        }       
                        var tcs = new TaskCompletionSource<HttpResponseMessage>();    
                        tcs.SetResult(response);    
                        return tcs.Task;
                    }
                    catch
                    {
                        var tcs = new TaskCompletionSource<HttpResponseMessage>();    
                        tcs.SetResult(response);    
                        return tcs.Task;
                    }
                }    
                return base.SendAsync(request, cancellationToken).ContinueWith(t =>
                {
                    HttpResponseMessage resp = t.Result;

                    resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());    
                    return resp;
                });
            }    
            return base.SendAsync(request, cancellationToken);
        }
    }

使用ajax从不同的域(即abc.in)获取记录时没有问题,它会回复数据。但是当我尝试使用上面的ajax调用发布数据时,它会给出

XMLHttpRequest cannot load http://abc.in/api/api/Patient/Create. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:56139' is therefore not allowed access. 

我错过了什么吗?通过使用谷歌提供的高级休息客户端应用程序,可以成功创建记录。我的ajax电话丢失了吗?

1 个答案:

答案 0 :(得分:0)

嗯,这可能有点帮助 click me

function getJSON(url) {  
var script = document.createElement('script');
script.setAttribute('src', url);
script.setAttribute('type', 'text/javascript');
document.getElementsByTagName('head')[0].appendChild(script);
}