Dojo.request для iteminfo — код возврата 200 в Fiddler, но 0 в браузере

Я использую тот же код для dojo.request, что и в предыдущем проекте, за исключением URL-адреса и того факта, что я вызываю службу iteminfo вместо addFeatures слоя. Однако я всегда получаю следующую ошибку:

Unable to load http://foobar.com/arcgis/rest/services/MapServer/info/iteminfo status: 0

Я подтвердил это в Firefox и IE. Статус, отображаемый Firebug или Visual Studio, всегда равен 0, даже если статус, отображаемый в Fiddler, равен 200. Он также показывает 0, когда я что-то путаю и получаю 401 в Fiddler.

Итак, вот мой код:

var promise = require('dojo/request').post(uri, {
    handleAs: "json",
    query: "f=pjson",        
    headers: {
        "X-Requested-With": null
    },
    //timeout: 60000,  //commenting this in and out changes nothing
    withCredentials: true
});

var res = promise.isResolved();
var rej = promise.isRejected();
var ful = promise.isFulfilled();
var can = promise.isCanceled();
var respres = promise.response.isResolved();
var resprej = promise.response.isRejected();
var respful = promise.response.isFulfilled();
var respcan = promise.response.isCanceled();

promise.response.then(
  //success
  function (response) {
    //something
  },
  //fail
  function (error) {
    //something different
  }
);

Мне нужен вывод в формате JSON, поэтому я добавил параметр query; без него Fiddler вместо этого отображает выходные данные в формате HTML. Я нашел ответ, указывающий, что для ответа может потребоваться время, но либо это не мой случай, либо что-то более сложное, чем простой вариант timeout необходим.

Все мои тестовые переменные (res,rej...) содержат false. Таким образом, запрос кажется нерешенным, невыполненным и т. Д. В коде, но Fiddler возвращает ответ - я недостаточно разбираюсь в этих сетевых искусствах, чтобы сделать из этого вывод, поэтому я задаю вопрос.

Кроме того, у меня смутное впечатление, что некоторые дополнительные заголовки должны быть решением. Я пытался добавить accept (ничего не изменилось) и content-type (получилось pre-flight и Fiddler сообщил о статусе 401).

РЕДАКТИРОВАТЬ: заголовок ответа содержит следующую информацию о безопасности:

Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Origin: http://localhost:30322 //origin for now
Access-Control-Allow-Origin: *

person Pavel V.    schedule 06.01.2016    source источник


Ответы (2)


Браузеры становятся более строгими (из соображений безопасности) в отношении выполнения междоменных запросов и могут просто отказаться загружать междоменный ресурс, даже если он имеет статус 200, и вместо этого отображать 0. Таким образом, если домен в uri который вы используете в своем запросе dojo, отличается от домена в uri вашего сайта, это может быть проблемой.

Обратите внимание, что простое добавление номера порта соответствует другому домену и будет считаться междоменным запросом.

Чтобы обойти это, вы можете либо сделать все запросы в своем домене, либо добавить что-то в свой uri запроса dojo, чтобы ваш веб-сервер прокси-сервер запрашивал запросы на внешний сервер, например:

    RewriteRule /arcgis/(.*)  http://foobar.com/arcgis/$1 [L,P]
    ProxyPassReverse /arcgis http://foobar.com/arcgis

В противном случае вам придется вручную указать, что междоменные запросы с домена вашего сайта разрешены. Сервер foobar.com должен добавить заголовок HTTP Access-Control-Allow-Origin со значением вашего домена в ответ, и ваш браузер примет его. Добавление заголовка Access-Control-Allow-Origin со значением * позволит принимать междоменные запросы из любого домена, но, очевидно, менее безопасно.

person greenkarmic    schedule 06.01.2016
comment
Я недостаточно ясно объяснил тот факт, что я знаю, что политика междоменной безопасности, вероятно, вызовет проблему, и я пропустил содержимое заголовков безопасности (сейчас добавлено в редактировании). Однако ваш ответ заставил меня еще раз задуматься об использовании прокси: на самом деле мы будем использовать прокси в продакшне, поэтому использование прокси (даже одного для другого проекта) — это пока выход. Однако мне любопытно, почему заголовок Access-Control-Allow-Origin не решил эту проблему. - person Pavel V.; 07.01.2016
comment
Хорошая идея, мы также используем прокси в продакшене, чтобы полностью обойти проблемы с cors. - person greenkarmic; 07.01.2016
comment
Также на стороне клиента мы указываем эти заголовки в запросе dojo: 'Content-Type': application/x-www-form-urlencoded; charset=UTF-8 и 'X-Requested-With': - person greenkarmic; 07.01.2016

Я попытался выполнить предварительную проверку запроса. Отправленный запрос OPTIONS выглядел нормально, но наш сервер требовал аутентификации с ним, что приводило к ошибке 401. Я не хочу пытаться взломать запрос OPTIONS, так что это действительно разрешимо только на стороне сервера. Поскольку целью всего этого является только тестирование, а в производстве все будет на этом сервере или за прокси-серверами, мы решили использовать какой-то грязный обходной путь, например кэширование JSON в файле.

Что касается загадки, почему Access-Control-Allow-Origin было недостаточно, я предполагаю, что виноват POST. Он несовместим как с JSON-P, так и с простыми запросами CORS. Кроме того, у меня никогда не было заголовка ответа Access-Control-Allow-Methods, поэтому их отсутствие могло заблокировать запрос. Хотя я не уверен в этом.

person Pavel V.    schedule 04.02.2016