WedX - журнал о программировании и компьютерных науках

Междоменный JQuery AJAX POST не завершается после того, как OPTIONS возвращает 200

У меня есть встроенный сервер Jetty v9.2.10 с настроенным фильтром перекрестного происхождения (org.eclipse.jetty.servlets.CrossOriginFilter). На сервере есть служба REST, которую я пытаюсь отправить с помощью jQuery. Попытка POST доходит до запроса OPTIONS в Firefox; обмен происходит следующим образом:

Заголовки запроса

Host: localhost:8402
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: https://localhost
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

Заголовки ответа

Allow: HEAD, POST, GET, OPTIONS
Content-Length: 24
Content-Type: text/plain
Date: Wed, 12 Aug 2015 00:57:35 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(9.2.10.v20150310)

(Примечательно, что нет ни одного из заголовков Access-Control, которые я ожидал бы увидеть в ответе.) Если я попробую это в Chrome, его сетевой отладчик скажет мне, что ответ на запрос OPTIONS небезопасен, поэтому я не могу даже посмотреть, что вернется, но это, наверное, отдельная тема.

Вот JavaScript, который делает запрос:

    $(document).ready(function(){
        var queryString = URI.parseQuery(URI(window.location.href).search()); 
        var cred = "/*a really long token*/";
        $.ajax({
                type: "POST",
                url: "https://localhost:8402/api/v1/resource/agent/" + queryString.agentId + "/connector?token=" + cred,
                data: {
                    //some JSON
                },
                success: function(data,status){
                    alert("Response: " + data + "\nStatus: " + status);
                },
                crossDomain: true,
                contentType: 'application/json'
        });
    });

Вот метод, в котором я устанавливаю фильтр CORS на сервере:

private void addCorsFilter(ServletContextHandler servletHandler)
{
    FilterHolder corsFilter = servletHandler.addFilter(CrossOriginFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
    // this string is set to "http(s?)://localhost*" as I have everything running locally right now, but setting to "*" doesn't make a difference
    String studioDomain = environmentVariableReader.read(Constants.Env.STUDIO_DOMAIN);
    corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, studioDomain);
    corsFilter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
    corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD,PUT,OPTIONS");
    corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
    corsFilter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
    logger.info("cross-origin filter allowing {}", studioDomain);
}

Я попытался настроить CrossOriginFilter, используя инструкции из обоих ответов здесь - а также использование подстановочных знаков для многих полей - но большинство конфигураций дают мне тот же результат. Я могу предоставить соответствующие журналы Jetty, если они помогут.


  • После вашего server.start() добавьте server.dumpStdErr() и убедитесь, что ваш CrossOriginFilter присутствует. 13.08.2015
  • @JoakimErdfelt Дамп показывает, что фильтр начинается с правильных параметров, и я проверил, что ServletContextHandler имеет его в своей коллекции фильтров, используя отладчик. 13.08.2015

Ответы:


1

Проблема оказалась ни с чем здесь не связанной. Фильтрация на самом деле выполнялась Guice, и он делегировал цепочку фильтров Jetty только после того, как прошел через известные ему фильтры и попытался обслужить запрос с помощью введенного им сервлета. Я не знал об этом, поэтому я не добавил CrossOriginFilter к ServletModule Guice. В результате Guice попытался обслужить запрос с помощью внедренного им сервлета диспетчера RESTEasy (поэтому ответ выглядел как HttpServlet.doOptions() по умолчанию) и не стал использовать цепочку фильтров Jetty, поскольку запрос был обслужен.

20.08.2015
Новые материалы

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

ИИ в аэрокосмической отрасли
Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


Для любых предложений по сайту: [email protected]