2017-01-23 1 views
1

Je modélise la couche d'authentification pour une application de réaction/redux simple. Du côté serveur, j'ai une API basée sur le gem devise_token_auth.extrait à la fois JSON et les en-têtes de fetch()

J'utilise fetch pour poster un signe demande:

const JSON_HEADERS = new Headers({ 
    'Content-Type': 'application/json' 
}); 

export const postLogin = ({ email, password }) => fetch(
    `${API_ROOT}/v1/auth/sign_in`, { 
    method: 'POST', 
    headers: JSON_HEADERS, 
    body: JSON.stringify({ email, password }) 
}); 

// postLogin({ email: '[email protected]', password: 'whatever' }); 

Cela fonctionne, et je reçois une réponse 200 et toutes les données dont j'ai besoin. Mon problème est, l'information est divisée entre le corps de la réponse et les en-têtes.

  • Corps: informations utilisateur
  • têtes: accès-token, expiration, etc.

Je pourrais analyser le corps JSON cette façon:

postLogin({ '[email protected]', password: 'whatever' }) 
    .then(res => res.json()) 
    .then(resJson => dispatch(myAction(resJson)) 

Mais myAction ne serait pas obtenir des données à partir des en-têtes (perdues lors de l'analyse JSON).

Existe-t-il un moyen d'obtenir à la fois les en-têtes et le corps d'une demande fetch? Merci!

Répondre

1

Je pensais que je partage la façon dont nous avons finalement résolu ce problème: en ajoutant simplement une étape dans la chaîne .then (avant l'analyse du JSON) pour analyser les en-têtes de auth et envoyer l'action appropriée:

fetch('/some/url') 
    .then(res => { 
    const authHeaders = ['access-token', 'client', 'uid'] 
     .reduce((result, key) => { 
     let val = res.headers.get(key); 
     if (val) { 
      result[key] = val; 
     } 
     }, {}); 
    store.dispatch(doSomethingWith(authHeaders)); // or localStorage 
    return res; 
    }) 
    .then(res => res.json()) 
    .then(jsonResponse => doSomethingElseWith(jsonResponse)) 

Une approche plus inspirée par la puissante Dan Abramov (http://stackoverflow.com/a/37099629/1463770)

fetch('/some/url') 
    .then(res => res.json().then(json => ({ 
    headers: res.headers, 
    status: res.status, 
    json 
    })) 
.then({ headers, status, json } => goCrazyWith(headers, status, json)); 

HTH

0

Peut être comme ceci:

postLogin({ '[email protected]', password: 'whatever' }) 
    .then(res => { 
    processHeader(res.headers.raw()) 
    dispatch(myAction(res.json())) 
    }) 
+0

Salut, merci pour votre réponse. Malheureusement, le 'myAction' devrait prendre une promesse comme argument puisque res.json() renvoie un. Nous voulons transmettre des données simples aux créateurs d'actions non-thunk. – nerfologist