2013-04-02 11 views
16

Od kilku tygodni staram się uzyskać jedną z moich usług sieciowych opartych na domenie jQuery AJAX SOAP do pracy z wtyczki jQuery, którą napisałem dla jednego moich klientów. Większość przeprowadzonych przeze mnie badań zdawała się wskazywać, że nie było to możliwe, ponieważ CORS lub Cross Origin Resource Sharing dopuszczałyby tylko wywołania typu jasonP (GET).Usługi sieciowe oparte na bazie JQuery AJAX SOAP i CORS (współdzielenie zasobów pochodzących z różnych źródeł)

W końcu wymyśliłem, jak sprawić, żeby działało i pomyślałem, że podzielę się tym, co musiałem zrobić.

Pierwszą rzeczą, którą należy zrozumieć, jest to, że w przeglądarce obsługującej CORS, gdzie serwer znajduje się w innej domenie, wszystko inne, co GET (wśród innych parametrów) spowoduje, że zostanie to nazwane sprawdzeniem wstępnym. Oznacza to, że przeglądarka poprosi serwer o listę opcji, które może wykonać. Jeśli serwer nie zwróci dokładnej listy opcji umożliwiających usługę WWW opartą na protokole SOAP, wywołanie zakończy się niepowodzeniem, nawet przed wykonaniem faktycznego żądania.

Co musisz zrobić, aby serwer WWW (w moim przykładzie to IIS7.5) zwróci poprawną listę opcji.
Dokonujesz tego, konfigurując plik web.config w folderze inetpub \ wwwroot (jeśli nie masz, po prostu utwórz i skopiuj do niego).

Mój plik web.config wygląda następująco.

Ważne jest, aby rozróżniać małe i wielkie litery kiedy zdałem sobie sprawę, że wszystko działało zgodnie z oczekiwaniami.

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
<system.webServer> 
    <httpProtocol> 
    <customHeaders> 
    <add name="Access-Control-Allow-Origin" value="*" /> 
    <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, PUT, DELETE" /> 
    <add name="Access-Control-Allow-Headers" value="content-type,soapaction,x-requested-with" />  
    </customHeaders> 
    </httpProtocol> 
     <handlers accessPolicy="Read, Execute, Script" /> 
</system.webServer> 
</configuration> 

Mój kod jQuery AJAX wygląda tak.

var getNextJobId = function() 
{ 
    var se = ''; 
    se = se + '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'; 
    se = se + '<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">'; 
    se = se + '<soap-env:Body>'; 
    se = se + '<ebas:getNextJobIdRequest xmlns:ebas="http://www.ebasetech.com">'; 
    se = se + '<ebas:ORGCODE>' + plugin.settings.orgcode + '</ebas:ORGCODE>'; 
    se = se + '</ebas:getNextJobIdRequest>'; 
    se = se + '</soap-env:Body>'; 
    se = se + '</soap-env:Envelope>'; 
    $.ajax(
    { 
    url: params.webserviceTargetUrl, 
beforeSend: function(xhr) 
{ 
    xhr.setRequestHeader("SOAPAction", "getNextJobId"); 
}, 
type: "POST", 
dataType: "xml", 
data: se, 
crossDomain: true, 
headers: {"X-Requested-With": "XMLHttpRequest"}, 
async: false, 
success: function(xml) 
{ 
    params.jobId = $(xml).find("ebas\:JOBID").text(); 
}, 
failure: function(xml) 
{ 
    params.webserviceFailure = $(xml).text(); 
}, 
     contentType: "charset=UTF-8" 
}); 
} 
+2

Zmień "błąd" na "błąd". –

+0

+1 dla SOAP w jQuery – Imdad

+0

To pytanie wydaje się być nie na temat, ponieważ nie spełnia naszego [formatu Q & A dla tych pytań, na które udzielono odpowiedzi] (http://blog.stackoverflow.com/2011/07/its-ok -to-ask-and-answer-your-questions-questions /). Rozważ oddzielenie odpowiedzi od pytania. – Gordon

Odpowiedz

4

"to nie było możliwe, ponieważ CORS lub Cross-Origin Resource Sharing pozwoliłby tylko jasonP (GET) Rodzaj połączenia."

CORS nie ogranicza się do metod GET, ani nie jest ograniczony do wywołań w stylu JSONP.

JSONP jest techniką stosowaną przez twórców stron internetowych przed standaryzacją CORS, aby wykonać żądanie AJAX dla hostów innych niż ten, który obsługiwał stronę. JSONP działa poprzez wstawienie do strony znacznika <script>. Wymaga on udziału serwera, zwykle poprzez zawijanie wyników JSON w wywołaniu funkcji nazwanej w wywołaniu AJAX za pomocą parametru callback. Zobacz tę odpowiedź: what-is-jsonp-all-about.

Jak zauważyłeś, JSONP ogranicza się do wykonywania metody GET, ponieważ <script> wykonuje tylko GET. Ma również inne problemy, takie jak brak możliwości obsługi błędów. Na przykład, jeśli zwracana jest odpowiedź 400, skrypt po prostu nie jest wykonywany przez przeglądarkę, zamiast wykonywania obsługi błędów JS dla wywołania AJAX.

CORS to nowszy standard. Wymaga to również udziału serwera, ponieważ musi obsługiwać sprawdzanie preflightów i używa dodatkowych nagłówków HTTP, takich jak: Access-Control-Allow-Origin, Access-Control-Allow-Methods i Access-Control-Allow-Headers, które dobrze opisałeś w edycji na swoje pytanie. Nie ogranicza się do metod GET. Jest raczej ograniczony do metod określonych przez wyniki sprawdzenia preflight w nagłówku Access-Control-Allow-Methods. CORS nie wymaga zawijania wyników w funkcji wywołania zwrotnego ani żadnej innej korekty wyników, a także obsługuje błędy i inne kody stanu.Zobacz ten znakomity overview of CORS, aby uzyskać więcej informacji.

+0

Kilka dobrych dodatkowych informacji tutaj oraz w dołączonym linku. Dzięki wam obojgu. –

Powiązane problemy