JQuery utknął w preflight CORS i odpowiedzi ghostów IIS

Utknąłem. Poważnie... - rozwiązany. Czytaj :)

Scenariusz: Próbuję postąpić właściwie. Dodałem funkcjonalność CORS do mojej usługi REST (ASP.NET Web-API) opierając się na Thinktecture Identitymodel CORS DelegatingHandler. Jak na razie dobrze.

Aby sprawdzić, czy działa, wykonałem następujące czynności:

Ustawiłem prostą stronę HTML i opublikowałem ją na innym hoście niż usługa odpoczynku (xttp: // otherhost / simplewebpage). Strona używa JQuery do wykonania przykładowego żądania. Kod patrz poniżej.Następnie ustawiam moją usługę odpoczynku, aby nie używać iis express, ale w pełni rozwiniętą instancję tego działającą na moim komputerze programistycznym (xttp: // developmenthost / restservice).Wreszcie na moim komputerze programistycznym otwieram xhostp: // inny host / stronę prostą i odpalam żądanie Ajax. Wywołanie błędu jest wykonywane informując mnie, że w Chrome wystąpił „błąd transportu” (IE9) lub „” (pusty ciąg). Upewniłem się, że nie ma problemu z łącznością proxy lub czegoś podobnego.

Więc poszedłem i spojrzałem na ślady skrzypków i logi IIS. Fiddler mówi, że nie ma żądania GET / rest / hello, lecz raczej OPCJE / rest / hello - co jest całkowicie w porządku i oczekiwane! Jednak odpowiedź na żądanie OPTIONS jest dość intrygująca!

Cały nagłówek odpowiedzi wygląda tak:

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/7.5
Public: OPTIONS, TRACE, GET, HEAD, POST
Date: Fri, 15 Feb 2013 14:09:27 GMT
Content-Length: 0

To oczywiście nie jest nawet bliskie oczekiwanej odpowiedzi.Zabawną częścią tego jest to, że Request nawet nie trafił Application_BeginRequest () w mojej aplikacji. Więc moja aplikacja nie może być odpowiedzialna za ten wynik. Widzę żądanie w moich dziennikach IIS, a IIS dodaje nagłówek Powered-by-ASP.NET .. więc zdecydowanie przechodzi przez (prawą) witrynę IIS.

Kod JQuery, który wyzwala żądanie ajax:

    function Run()
    {
        $.ajax({
            type: 'GET',
            url: url,
            dataType: "json",
            beforeSend: function(jqXhr) {
                jqXhr.setRequestHeader("Authorization", "Basic " + getBasicHttpEncodedString(userName, password));
                jqXhr.setRequestHeader("Api-Key", "123");
            },
            success: successCallback,
            error: errorCallback,
            timeout: 180*1000
        });
    }

Wynikowe zapytanie OPCJE wygląda tak:

OPTIONS http://services.dev13/Rest/Hello HTTP/1.1
Host: developmenthost
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://otherhost/simplewebpage
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
Access-Control-Request-Headers: accept, origin, api-key, authorization
Accept: */*
DNT: 1
Referer: http://otherhost/simplewebpage
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

... i widziałeś już odpowiedź na powyższe.

Każdy pomysł, kto dokładnie odpowiada na moje żądanie OPCJE? Czy mój kod JQuery jest wadliwy? Usługa REST działa dobrze, jeśli używam np. Listonosza (Google Chrome App) lub jeśli fałszuję Żądania w Skrzypku (Prawdopodobnie dlatego, że nie wykonują negocjacji CORS - nie ma żądania OPCJE).

Aktualizacja nr 1: Wcześniej czytałem gdzieś, że wyłączenie WebDAV jest obowiązkowe, ponieważ koliduje z żądaniami OPTIONS. Mój widok usług roli IIS mówi mi, że publikowanie WebDAV jestNie zainstalowany.

* Aktualizacja # 2: * Problem rozwiązany?? Kopałem głębiej. W IIS jest zarejestrowany moduł odpowiedzialny za „niepożądaną (?)” Odpowiedź na żądanie OPCJE. Jego nazwa to „OPTIONSVerbHandler” (handler: ProtocolSupportModule). Jeśli wyłączę ten moduł, żądanie przechodzi do mojej aplikacji. Tam powstaje bardziej znacząca odpowiedź, a następniepo którym następuje faktyczne żądanie GET! YAY!

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://otherhost/simplewebpage
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept,origin,api-key,authorization
X-AspNet-Version: 4.0.30319
Date: Fri, 15 Feb 2013 15:09:25 GMT
Content-Length: 0

Kiedy już wiesz, gdzie jest problem, znajdziesz mnóstwo zasobów, które każą ci upewnić się, że web.config wygląda tak: - /

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="false">
      <remove name="WebDAVModule" />
    </modules>
    <handlers>
      <remove name="OPTIONSVerbHandler" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

Jednak nadal nie działa w IE9 („błąd: brak transportu”). Na wypadek, gdyby ktoś poszedł tą samą drogą, co ja -> to jest sprawa IE9:https://stackoverflow.com/a/10232313/1407618

questionAnswers(2)

yourAnswerToTheQuestion