2012-09-28 17 views
6

Questo argomento sembra essere uno con un milione di "soluzioni" con risultati ancora più misti. Quindi, per favore, tagliami un po 'di tempo mentre cercherò di dimostrare cosa sta succedendo, cosa sto usando e come ho tentato di risolvere il problema.asmx servizio Web - jQuery ajax post json (errore 500) - CORS (Access-Control-Allow-Origin è impostato su *)

Il mio ambiente di test è in esecuzione IIS6 asp.net 2.0, ho configurarlo con

'Access-Control-Allow-Origin' * 

Ho anche impostare i verbi per .asmx estensioni per

"GET,HEAD,POST,DEBUG,OPTIONS" 

tramite jQuery v1. 7.2 Chiamate ajax() Sono in grado di ottenere file xml dal sever e POST a un servizio di base che restituisce una stringa con i risultati attesi su un dominio incrociato. Quindi so almeno parzialmente che le mie richieste di dominio incrociato funzionano.

Il mio problema si pone quando inizio ad espandersi su questo, e utilizzare JSON per inviare i dati al servizio

Ho un metodo semplice ASMX webservice:

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

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

      return sr; 
     } 

magia Molto semplice, e non molto succede lì, tutto quello che voglio fare è passare l'oggetto 'SubRequestXX' dentro, e per ora semplicemente convalidarlo è arrivato lì e rispondere.

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

Forse la risposta sta lì? ma ecco quali sono i dati RAW del violinista mi mostra utilizzando lo stesso codice esatto JS da una pagina sullo stesso dominio (il successo - codice di risultato 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]"}} 

quindi tutto sembra grande e si comporta come previsto. Ora, se io prendo lo stesso codice HTML/JS, distribuire su un altro server e fare la stessa richiesta (cross-site) spettacoli violinista (fallisce codice di risultato 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 

Molti risultati della ricerca suggeriscono un paio di web. modifiche di configurazione. se posso aggiungere quanto segue alla mia sezione system.web:

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

quindi la mia richiesta appare come

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 

e la mia risposta:

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) 

Così aggiungendo che la sezione nel mio spazio web. la configurazione ha fatto qualcosa visto che i miei risultati sono leggermente diversi. Ma non sono in grado di discernere cosa.

Altre soluzioni suggeriscono queste impostazioni di configurazione web dal momento che sto usando asp.net 2.0, notare che ho lasciato questi come mostrato durante tutti i risultati di cui sopra, commentate quelle sono originali, dalla creazione del progetto:

 <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> 

Così ... la grande domanda ... Perché le mie richieste cross-site falliscono con lo stesso codice, nonostante tutto quanto sopra? Sembra che non appena la richiesta proviene da un altro dominio soffoca su JSON.

Qualsiasi aiuto sarebbe molto apprezzato per risolvere questo mistero. Presumo sia un'impostazione IIS6 (server) o il mio $.chiamata ajax() e mi sembra che sia probabilmente qualcosa di semplice o di piccolo, ma non riesco a metterci il dito sopra.

risposta

0

Ho provato qualcosa simillar tramite JSONP. Penso di aver basato la soluzione su questo articolo.

JSONP + CORS

Un'altra cosa potenziale è che mettere in JSON come una stringa a un servizio WCF in genere non finisce bene (so che questo non è WCF, solo dicendo che potrebbe essere lo stesso problema). Io di solito faccio questo:

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

L'uso di JSON.parse sarà anche prendere qualsiasi cattiva JSON che attraversa.

Spero che questo risolva il problema.