Brakujący X-Requested-With: XMLHttpRequest (powoduje 200 OK, ale wyświetla się jako błąd?)

Kiedy pobieram dane z mojego lokalnego hosta jako JSON, wszystko jest w porządku. Kiedy próbuję pobrać dane JSON ze zdalnej maszyny, wszystko też jest w porządku. Mogę przeanalizować, że dane JSON pochodzą z mojego hosta lokalnego do obiektów (wtyczka datagrid: renderuje ją jqgrid). Jednak gdy próbuję użyć zdalnego źródła, tak się nie dzieje. W firebugu mówi 200 OK, ale pokazuje ikonę błędu i pisze na czerwono. Sprawdziłem różnice między moim lokalnym hostem a nagłówkiem połączenia zdalnego i stwierdziłem, że nie ma tego nagłówka przy połączeniu zdalnym:

X-Requested-With    XMLHttpRequest

Myślę, że może to być problem. Nie ustawiałem tego i działało dobrze. Występuje na żądanie zdalne.

Jakieś pomysły na rozwiązanie tego problemu?

PS: Próbowałem ustawić nagłówki Ajax, ale nie zadziałało:

    $.ajaxSetup({
          headers: {"X-Requested-With":"XMLHttpRequest"}
    });

    $("#userTable").jqGrid({
        url:'http://xx.xx.x.xxx:8080/aa/bb/cc/user',
        colNames:['User Name','Password'],
        colModel:[
            {name:'userName',index:'userName', width:100},
            {name:'password',index:'password', width:55}
        ],
        jsonReader: ...
        ...
    });

Kiedy używam tej konfiguracji, nie widzę nawet żądania GET z Firebug.

PS: Używam Spring 3 z REST i Tomcat jako serwera WWW.


person kamaci    schedule 20.10.2011    source źródło
comment
Spójrz na tutaj, jeśli potrzebujesz zaimplementować JSONP w Spring.   -  person Oleg    schedule 20.10.2011


Odpowiedzi (1)


Myślę, że masz problem z Cross-site scripting. Problem można rozwiązać, jeśli serwer ustawi jakieś dodatkowe opcje w nagłówku HTTP odpowiedzi. Tak więc rozwiązanie nie polega na modyfikowaniu kodu klienta, jak to robisz obecnie, ale na kodzie serwera.

Zalecam sprawdzenie opcji HTTP, które zostaną ustawione w nagłówku HTTP przez tables.googlelabs.com używane w demo z odpowiedzi. Zobaczysz, że odpowiedź serwera zawiera następujące dodatkowe opcje HTTP:

X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block

a odpowiedź JSON zostanie umieszczona wewnątrz wywołania funkcji zdefiniowanej przez parametr jsonCallback. Jeśli użyjesz jsonCallback=? jqGrid wygeneruje nazwę funkcji (coś jak jQuery16407707202236448429_1319101394784). Możesz przeczytać więcej o opcji X-XSS-Protection tutaj i o opcji X-Content-Type-Options: nosniff tutaj.

Jak możesz zobaczyć w demo, dane będą wyświetlane w jqGrid, więc Cross-site scripting może być zaimplementowany w jqGrid.

Ponieważ nazywamy serwer tables.googlelabs.com, który nie obsługuje parametrów stronicowania i sortowania jqGrid, użyłem w demie

url: 'http://tables.googlelabs.com/api/query?jsonCallback=?',
postData: "sql=" + encodeURIComponent("SELECT * FROM 333136 LIMIT 10")

Użycie ciągu znaków zamiast obiektu jako wartości postData spowoduje zastąpienie wszystkich innych parametrów jqGrid, które są zwykle publikowane. W Twoim przypadku nie będzie to potrzebne i prawdopodobnie wystarczy użyć url: 'http://xx.xx.x.xxx:8080/aa/bb/cc/user?jsonCallback=?'.

W każdym razie potrzebujesz zaimplementować obsługę JSONP na swoim serwerze. Oznacza to tylko, że serwer powinien "zrozumieć" parametr jsonCallback. Implementacja zależy od implementacji po stronie serwera. Może to być po prostu ustawienie crossDomainScriptAccessEnabled="true" powiązania dla webHttpBinding w przypadku usługi WCF (zobacz tutaj przykład web.config). Zobacz tę odpowiedź i ten (lub ten) dodatkowo dla usług sieci Web ASP.NET i ASP.NET MVC.

person Oleg    schedule 20.10.2011