React/Redux + суперагент, первый вызов прерывается

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

Мой создатель действий выглядит так

export function getSearchResults(searchQuery) {
return {
        query: searchQuery,
        type: actions.GO_TO_SEARCH_RESULTS
    }
}

Здесь он попадает в логику промежуточного программного обеспечения:

var defaultURL = '/myServer/mySearch';

callPendingAction();

superagent.get(defaultURL)
        .query({query: action.query})
        .end(requestDone);


//sets state pending so we can use loading spinner
function callPendingAction() {
    action.middlewares.searchIRC.readyState = READY_STATES.PENDING;
    next(action);
}

//return error or response accordingly
function requestDone(err, response) {
    console.log("call error", err);
    const search = action.search;
    if (err) {
        search.readyState = READY_STATES.FAILURE;
        if (response) {
            search.error = response.err;
        } else if (err.message) {
            search.error = err.message;
        } else {
            search.error = err;
        }
    } else {
        search.readyState = READY_STATES.SUCCESS;
        search.results = fromJS(response.body);
    }
    return next(action);
}

Запрос правильный, даже когда вызов завершен, я получаю это сообщение об ошибке:

Request has been terminated
Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.
at Request.crossDomainError (http://localhost:8000/bundle.js:28339:14)
at XMLHttpRequest.xhr.onreadystatechange (http://localhost:8000/bundle.js:28409:20)

Кажется, страница тоже обновляется каждый раз.

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

ОБНОВЛЕНИЕ: кажется, это связано с хромом, я на Version 47.0.2526.80 (64-bit). Это приложение является iframe внутри другого приложения, и я считаю, что это вызывает проблему с Chrome, потому что, когда я пытаюсь это сделать в Firefox, проблем нет. Что странно, только первый вызов выдает ошибку CORS, потом вроде исправляется. Если у кого-то есть вход или обходной путь, я был бы очень признателен. Спасибо за чтение.


person ajmajmajma    schedule 23.12.2015    source источник
comment
У меня такая же проблема в настоящее время. Использование Chrome 50.0.2661.86. Ни в Firefox 45.0.2, ни в Firefox 46.0 такой проблемы не было. Сафари тоже работает. Я еще не использую редукцию, поэтому не думаю, что это связано с этим. Для сервера API я использую Koa с модулем npm kcors для CORS. withCredentials не работает, но это потому, что CORS перестает работать вместе, когда я добавляю withCredentials.   -  person Drew Goodwin    schedule 28.04.2016


Ответы (3)


Была такая же проблема, только что понял благодаря ответу, предоставленному @KietIG в теме ReactJS с React Router - странное поведение маршрутизации в Chrome.

Ответ не имел ничего общего с CORS. Запрос был отменен, так как Chrome ушел со страницы в середине запроса. Это произошло из-за того, что event.preventDefault() не был вызван ни в одном из обработчиков отправки формы. Кажется, Chrome обрабатывает это иначе, чем другие браузеры.

Смотрите ссылку ответа выше для более подробной информации.

person Drew Goodwin    schedule 28.04.2016
comment
Была такая же проблема, но я не использую реакцию или редукцию. Кроме того, у меня нет элемента формы, я просто использую суперагент. Итак, где я должен вставить preventDefault? - person Skalár Wag; 03.03.2017
comment
В начале любого метода обработчика вызывается действие. - person Drew Goodwin; 04.03.2017

В моем случае это происходило, когда я пытался установить случайный заголовок HTTP-запроса (например, X-Test) на стороне клиента, и либо AWS Lambda отклонил его во время запроса OPTIONS, либо что-то еще сделало это.

person catamphetamine    schedule 11.04.2017

Я не знаю о побочных эффектах, но вы получаете ошибки CORS. Добавьте в запрос метод .withCredentials().

Из документов суперагента:

Метод .withCredentials() позволяет отправлять файлы cookie из источника, но только в том случае, если «Access-Control-Allow-Origin» не является подстановочным знаком («*»), а «Access-Control-Allow-Credentials» — « истинный".

Это должно исправить это:

superagent.get(defaultURL)
        .query({query: action.query})
        .withCredentials()
        .end(requestDone);

Дополнительную информацию о совместном использовании ресурсов между источниками можно найти здесь.

person danillouz    schedule 23.12.2015
comment
Я думал, что это правильная идея, но, похоже, она не работает. Я думаю, что это может быть ошибка с Chrome прямо сейчас из-за этой настройки. Спасибо за всю информацию! - person ajmajmajma; 23.12.2015
comment
У меня такая же проблема. Когда я добавляю withCredentails(), CORS вообще перестает работать. Не уверен, что первоначальная проблема будет решена, если я смогу исправить все, что происходит при добавлении withCredentails(). - person Drew Goodwin; 28.04.2016
comment
После дальнейшего тестирования опция withCredentials() не решила проблему (withCredentials заработал после добавления заголовка Access-Control-Allow-Credentials, но проблема, описанная в вопросе, осталась). - person Drew Goodwin; 28.04.2016