Отсутствует X-Requested-With: XMLHttpRequest (вызывает 200 OK, но отображается как ошибка?)

Когда я получаю данные с моего локального хоста в формате JSON, все в порядке. Когда я пытаюсь получить эти данные JSON с удаленной машины, все тоже в порядке. Я могу разобрать, что данные JSON поступают с моего локального хоста в объекты (плагин datagrid: jqgrid отображает их). Однако, когда я пытаюсь использовать удаленный источник, это не так. В firebug пишет 200 OK, но показывает значок ошибки и пишет красным. Я проверил различия между моими заголовками локального хоста и удаленного подключения и обнаружил, что при удаленном подключении этого заголовка нет:

X-Requested-With    XMLHttpRequest

Думаю проблема может быть в этом. Я его не ставил, и он работал хорошо. Это происходит по удаленному запросу.

Любые идеи, чтобы решить эту проблему?

PS: я пытался настроить заголовки Ajax, но это не сработало:

    $.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: ...
        ...
    });

Когда я использую эту настройку, я даже не вижу запроса GET от Firebug.

PS: я использую Spring 3 с REST и Tomcat в качестве веб-сервера.


person kamaci    schedule 20.10.2011    source источник
comment
Посмотрите на здесь, если вам нужно внедрить JSONP в Spring.   -  person Oleg    schedule 20.10.2011


Ответы (1)


Я думаю, что у вас проблема с межсайтовым скриптингом. Проблема может быть решена, если сервер установит некоторые дополнительные параметры в заголовке HTTP. ответа. Таким образом, решение заключается не в изменении клиентского кода, как вы делаете сейчас, а в серверном коде.

Я рекомендую вам изучить параметры HTTP, которые будут установлены в заголовке HTTP с помощью tables.googlelabs.com, используемого в демонстрация из ответа. Вы увидите, что ответ сервера имеет следующие дополнительные параметры HTTP:

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

и ответ JSON будет помещен внутри вызова функции, определенной параметром jsonCallback. Если вы будете использовать jsonCallback=?, jqGrid сгенерирует имя функции (что-то вроде jQuery16407707202236448429_1319101394784). Подробнее о параметре X-XSS-Protection можно прочитать здесь и о X-Content-Type-Options: nosniff опции здесь.

Как видно из демонстрации, данные будут отображается в jqGrid, поэтому межсайтовый скриптинг может быть реализован в jqGrid.

Поскольку мы вызываем сервер tables.googlelabs.com, который не поддерживает параметры подкачки и сортировки jqGrid, я использовал в демо

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

Использование строки вместо объекта в качестве значения postData заменит любые другие параметры jqGrid, которые обычно публикуются. В вашем случае этого делать не нужно и, вероятно, вам нужно просто использовать url: 'http://xx.xx.x.xxx:8080/aa/bb/cc/user?jsonCallback=?'.

В любом случае вам нужно реализовать поддержку JSONP на вашем сервере. Это просто означает, что сервер должен "понимать" параметр jsonCallback. Реализация зависит от вашей реализации на стороне сервера. Это может быть просто параметр привязки crossDomainScriptAccessEnabled="true" для webHttpBinding в случае службы WCF (см. >здесь пример web.config). См. этот ответ и этот (или этот) дополнительно для веб-служб ASP.NET и ASP.NET MVC.

person Oleg    schedule 20.10.2011