2015-12-23 1 views
5

J'écris une application rea-redux où je fais des appels de service dans mes middlewares en utilisant superagent. J'ai trouvé un comportement très étrange où le premier appel à ma recherche api se termine toujours. J'ai essayé d'attendre 10 à 30 secondes avant de faire le premier appel, et d'enregistrer chaque étape du processus et je n'arrive pas à comprendre pourquoi cela se produit.React/Redux + super agent, le premier appel se termine

Mon créateur d'action ressemble

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

Il frappe la logique middleware ici:

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); 
} 

La requête est correcte même lorsque l'appel est terminé, je reçois ce message err retour:

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) 

Il semble que la page soit rafraîchie à chaque fois.

Je n'arrive pas à trouver des indices sur la raison pour laquelle cela se produit, il semble que peu importe ce que le premier appel échoue, mais il est correct après le premier appel terminé. Apprécierait toute contribution, merci!

MISE À JOUR: il semble donc que cela soit lié au chrome, je suis sur Version 47.0.2526.80 (64-bit). Cette application est un iframe dans une autre application et je crois que cela cause un problème avec chrome parce que quand j'essaye cela dans Firefox, il n'y a pas de problème. Ce qui est étrange c'est que seulement le premier appel donne le numéro de CORS, alors il semble être corrigé par la suite. Si quelqu'un a des commentaires ou une solution de contournement, je l'apprécierais grandement. Merci d'avoir lu.

+0

J'ai le même problème actuellement. À l'aide de Chrome 50.0.2661.86. Ni Firefox 45.0.2 ni Firefox 46.0 ont eu le problème. Safari fonctionne aussi bien. Je n'utilise pas encore Redux, donc je ne pense pas que cela soit lié à ça. Pour le serveur API, j'utilise Koa avec le module npm kcors pour CORS. withCredentials ne semble pas fonctionner, mais c'est parce que CORS cesse de fonctionner tous ensemble lorsque j'ajoute withCredentials. –

Répondre

7

Avait le même problème, juste compris grâce à la answer provided by @KietIG sur le sujet ReactJS with React Router - strange routing behaviour on Chrome.

La réponse n'a rien à voir avec CORS. La demande a été annulée car Chrome s'était éloigné de la page au milieu de la demande. Cela se produisait parce que event.preventDefault() n'avait pas été appelée dans l'un des gestionnaires de soumission de formulaire. Il semble que Chrome gère cela différemment des autres navigateurs. Voir le lien de réponse ci-dessus pour plus de détails.

+1

Avait le même problème, mais je n'utilise pas réagir ou redux. De plus, je n'ai pas d'élément de formulaire, j'utilise simplement superagent. Alors, où dois-je insérer preventDefault? –

+0

Au début de la méthode de gestionnaire quel que soit appelé sur l'action. –

0

Je ne connais pas les effets secondaires, mais vous obtenez des erreurs CORS. Ajouter la méthode .withCredentials() à votre demande.

De la superagent docs: Méthode

Les .withCredentials() permet la possibilité d'envoyer des cookies à partir l'origine, mais seulement lorsque "Access-Control-Allow-Origin" est pas un caractère générique ("*"), et "Access-Control-Allow-Credentials" est "true".

Cela devrait corriger:

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

Plus d'informations sur le partage des ressources Cross Origin se trouve here.

+0

Je pensais que c'était la bonne idée, mais cela ne semble pas fonctionner. Je pense que c'est peut-être un bug avec le chrome en ce moment à cause de cette configuration. Merci pour toutes ces informations! – ajmajmajma

+0

J'ai le même problème. Quand j'ajoute withCredentails() CORS cesse de fonctionner complètement. Je ne sais pas si le problème d'origine serait résolu si je pouvais corriger ce qui se passe quand withCredentails() est ajouté. –

+0

Après un autre test, l'option withCredentials() n'a pas résolu le problème (withCredentials a été créé pour fonctionner une fois l'en-tête Access-Control-Allow-Credentials ajouté, mais le problème décrit dans la question est resté). –

1

Dans mon cas, cela se produisait lorsque j'essayais de définir un en-tête de requête HTTP aléatoire (comme X-Test) côté client et que AWS Lambda le rejetait lors de la requête OPTIONS ou quelque chose d'autre.