2012-09-28 28 views
6

Ten temat wydaje się być jednym z milionem "rozwiązań" o jeszcze bardziej mieszanych wynikach. Więc proszę cię, daj mi trochę luzu, bo spróbuję pokazać, co się dzieje, czego używam i jak próbowałem rozwiązać problem.serwis internetowy asmx - jQuery ajax post json (błąd 500) - CORS (Access-Control-Allow-Origin jest ustawiony na *)

Moje badania środowiska jest uruchomiony IIS6 ASP.NET 2.0, mam go skonfigurować z

'Access-Control-Allow-Origin' * 

mam ustawić także czasowniki dla .asmx rozszerzeń

"GET,HEAD,POST,DEBUG,OPTIONS" 

poprzez jQuery v1. 7.2 wywołania ajax() Mogę pobrać pliki xml z serwera, a POST do usługi podstawowej, która zwraca ciąg znaków z oczekiwanymi wynikami między domenami. Tak więc WIEM, że przynajmniej częściowo działają moje żądania międzydomenowe.

Mój problem pojawia się, gdy zacznę rozwijać na tym i użyć json do wysłania danych do usługi

mam prostą metodę ASMX webservices:

 [WebMethod] 
     [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
     public SubResponse HelloWorldX(SubRequestXX SubReq) 
     { 
      SubResponse sr = new SubResponse(); 

      sr.resultCode = "777"; 
      sr.resultMsg = "hello - " + SubReq.EmailAddress; 

      return sr; 
     } 

bardzo proste i nie wiele magicznych tak się dzieje, wszystko co chcę zrobić to przekazać obiekt "SubRequestXX", a na razie po prostu sprawdzić, czy dotarł na miejsce i odpowiedzieć.

Using jQuery: 

    $.ajax({ 
     type: "POST", 
     url: "http://somedomain/subscription/MyService.asmx/HelloWorldX", 
     processData: false, 
     data: '{ "SubReq" : {"EmailAddress":"[email protected]"} }', 
     dataType: "json", 
     contentType: "application/json; charset=utf-8", 
     cache: false, 
     success: function(data, textStatus, jqXHR) { 
      ajaxSucccess3(data, textStatus, jqXHR); 
     }, 
     error: function(jqXHR, textStatus, errorThrown) { 
      console.log("Retrieve Hello Failed (AJAX Error): " + jqXHR.statusText + " | " + textStatus + " | " + errorThrown); 
     } 
    }); 
} 

Być może odpowiedź leży tam? ale oto co dane RAW Fiddler pokazuje mi, stosując dokładnie ten sam kod JS ze strony w tej samej domenie (sukces - kod wynikowy 200):

REQUEST: 
    POST http://somedomain/subscription/Service.asmx/HelloWorldX HTTP/1.1 
    Accept: application/json, text/javascript, */*; q=0.01 
    Content-Type: application/json; charset=utf-8 
    X-Requested-With: XMLHttpRequest 
    Referer: http://somedomain/subscription/subscription_-cors.html 
    Accept-Language: en-us 
    Accept-Encoding: gzip, deflate 
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; 9LA) 
    Host: somedomain 
    Content-Length: 45 
    Connection: Keep-Alive 
    Pragma: no-cache 

    { "SubReq" : {"EmailAddress":"[email protected]"} } 

RESPONSE: 

    HTTP/1.1 200 OK 
    Date: Fri, 28 Sep 2012 16:59:15 GMT 
    Server: Microsoft-IIS/6.0 
    X-Powered-By: ASP.NET 
    Access-Control-Allow-Origin: * 
    X-AspNet-Version: 2.0.50727 
    Cache-Control: private, max-age=0 
    Content-Type: application/json; charset=utf-8 
    Content-Length: 147 

    {"d":{"__type":"SubService.DataObj.SubResponse","resultCode":"777","resultMsg":"hello - [email protected]"}} 

więc wszystko wygląda świetnie i zachowuje się zgodnie z oczekiwaniami. Teraz, jeśli biorę ten sam html/kod JS, wdrażać na innym serwerze i dokonać takiego samego wniosku (cross-site) Skrzypek pokazy (nie kod wynikowy 500):

REQUEST: 
    POST http://somedomain/subscription/Service.asmx/HelloWorldX HTTP/1.1 
    Accept: */* 
    Origin: http://www.crossdomainsite.com 
    Accept-Language: en-US 
    Accept-Encoding: gzip, deflate 
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; 9LA) 
    Host: somedomain 
    Content-Length: 0 
    Connection: Keep-Alive 
    Pragma: no-cache 


RESPONSE: 
HTTP/1.1 500 Internal Server Error 
Date: Fri, 28 Sep 2012 16:58:56 GMT 
Server: Microsoft-IIS/6.0 
X-Powered-By: ASP.NET 
Access-Control-Allow-Origin: * 
X-AspNet-Version: 2.0.50727 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Content-Length: 4732 

..... 

Request format is unrecognized for URL unexpectedly ending in '/HelloWorldX' 

..... 

[InvalidOperationException: Request format is unrecognized for URL unexpectedly ending in '/HelloWorldX'.] 
    System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +405961 
    System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +212 
    System.Web.Script.Services.ScriptHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) +47 
    System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) +193 
    System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +93 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 

Wiele wyników wyszukiwania sugerują kilka sieci. zmiany w konfiguracji. jeśli dodać następujące do mojego sekcji system.Web:

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

następnie moja prośba wygląda

POST http://somedomain/subscription/Service.asmx/HelloWorldX HTTP/1.1 
Accept: */* 
Origin: http://www.crossdomainsite.ca 
Accept-Language: en-US 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; 9LA) 
Host: somedomain 
Content-Length: 0 
Connection: Keep-Alive 
Pragma: no-cache 

I moja odpowiedź:

HTTP/1.1 500 Internal Server Error 
Date: Fri, 28 Sep 2012 17:37:00 GMT 
Server: Microsoft-IIS/6.0 
X-Powered-By: ASP.NET 
Access-Control-Allow-Origin: * 
X-AspNet-Version: 2.0.50727 
Cache-Control: private 
Content-Type: text/plain; charset=utf-8 
Content-Length: 461 

System.InvalidOperationException: HelloWorldX Web Service method name is not valid. 
    at System.Web.Services.Protocols.HttpServerProtocol.Initialize() 
    at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response) 
    at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) 

Więc dodając, że części do mojej sieci. config zrobił coś, ponieważ moje wyniki są nieco inne. Ale nie jestem w stanie rozróżnić co.

Inne rozwiązania sugerują te ustawienia web config ponieważ używam ASP.NET 2.0, trzeba pamiętać, zostawiłem te, jak pokazano w trakcie wszystkich powyższych wyników, wykomentowane nich to oryginały z tworzenia projektu:

 <httpHandlers> 
      <remove verb="*" path="*.asmx"/> 
      <!--<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>--> 
      <add path="*.asmx" verb="*" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 

      <!--<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>--> 
      <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 

      <!--<add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>--> 
      <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/> 
     </httpHandlers> 

Tak ... wielkie pytanie ... Dlaczego moje żądania międzystronowe zawodzą z tym samym kodem, pomimo wszystkich powyższych? Wygląda na to, jak tylko żądanie pochodzi z innej domeny, którą dławi JSON.

Każda pomoc byłaby bardzo ceniona w rozwiązaniu tej tajemnicy. Zakładam, że jest to albo ustawienie IIS6 (serwer), albo moje $.wywołanie ajax() i czuję, że to prawdopodobnie coś prostego lub małego, ale nie mogę tego dotknąć.

Odpowiedz

0

Próbowałem coś simillar przez JSONP. Myślę, że oparłem rozwiązanie na tym artykule.

JSONP + CORS

Innym potencjalnym rzeczą jest to, że wprowadzenie w JSON jako ciąg do usług WCF zazwyczaj nie kończy się dobrze (wiem, że to nie jest WCF, po prostu mówiąc, może to być ten sam problem). Zwykle robię to:

Using jQuery: 

$.ajax({ 
    type: "POST", 
    url: "http://somedomain/subscription/MyService.asmx/HelloWorldX", 
    processData: false, 
    data: JSON.parse('{ "SubReq" : {"EmailAddress":"[email protected]"} }'), 
    dataType: "json", 
    contentType: "application/json; charset=utf-8", 
    cache: false, 
    success: function(data, textStatus, jqXHR) { 
     ajaxSucccess3(data, textStatus, jqXHR); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     console.log("Retrieve Hello Failed (AJAX Error): " + jqXHR.statusText + " | " + textStatus + " | " + errorThrown); 
    } 
}); 
} 

Użycie JSON.parse również złapie każdy zły JSON, który przechodzi.

Mam nadzieję, że to rozwiąże problem.