2017-11-10 3 views
0

Ich habe ein Wizard-Formular erstellt, das ich ein wenig ändere. Jeder Schritt des Formulars ruft einige Daten von der API ab, wenn componentWillMount und wenn der Benutzer auf "Weiter" klickt, um zum nächsten Formularteil zu gelangen, rufe ich eine andere Aktion mit componentWillUnmout ab, um eine Aktualisierungsaktion (PUT) von der API zu senden.redux-saga Netzwerkfehler - OPTIONS Anfrage

Ich benutze Redux-Saga mit reagieren. Hier

ist die saga.js Datei:

import { call, put, takeEvery } from 'redux-saga/effects'; 
import accountApi from '../../api/account'; 
import * as actions from '../../actions'; 

import { 
    FETCH_ACCOUNT_REQUEST, 
    FETCH_ACCOUNT_SUCCESS, 
    UPDATE_ACCOUNT_REQUEST, 
    UPDATE_ACCOUNT_SUCCESS 
} from '../../actions/types'; 

export function* fetchAccount(action) { 
    const account = yield call(accountApi.fetchAccount, action.params); 
    yield put({ type: FETCH_ACCOUNT_SUCCESS, account: account }); 
} 

export function* updateAccount(action) { 
    const accountUpdated = yield call(accountApi.updateAccount, action.params, action.accountUpdated); 
    yield put({ type: UPDATE_ACCOUNT_SUCCESS, accountUpdated: accountUpdated }); 
} 

export function* accountListener() { 
    yield takeEvery(FETCH_ACCOUNT_REQUEST, fetchAccount); 
    yield takeEvery(UPDATE_ACCOUNT_REQUEST, updateAccount); 
} 

Es ist die API-Datei:

import axios from 'axios'; 

const baseUrl = '<link>'; 

const accountApi = { 
    fetchAccount(params) { 
     return axios.get(`${baseUrl}${params}`) 
      .then(response => { 
       return response.data 
      }) 
    }, 

    updateAccount(params, accountUpdated) { 
     return axios.put(`${baseUrl}${params}`, accountUpdated) 
      .then(response => { 
       return response.data 
      }) 
    } 
} 

export default accountApi; 

die Aktion:

import axios from 'axios'; 

import { 
    FETCH_ACCOUNT_REQUEST, 
    UPDATE_ACCOUNT_REQUEST 
} from './types'; 

export function fetchAccount(params) { 
    return { 
     type: FETCH_ACCOUNT_REQUEST, 
     params 
    } 
} 

export function updateAccount(params, accountUpdated) { 
    return { 
     type: UPDATE_ACCOUNT_REQUEST, 
     params, 
     accountUpdated 
    } 
} 

das Reduktions:

import { 
    FETCH_ACCOUNT_REQUEST, 
    FETCH_ACCOUNT_SUCCESS, 
    UPDATE_ACCOUNT_REQUEST, 
    UPDATE_ACCOUNT_SUCCESS 
} from '../actions/types'; 

export default function(state = null, action) { 
    switch (action.type) { 
     case FETCH_ACCOUNT_REQUEST: 
      return null; 
     case FETCH_ACCOUNT_SUCCESS: 
      return action.account; 
     case UPDATE_ACCOUNT_REQUEST: 
      return null; 
     case UPDATE_ACCOUNT_SUCCESS: 
      return action.accountUpdated; 
     default: 
      return state; 
    } 
} 

und die Komponente:

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { bindActionCreators } from 'redux'; 
import { Field, reduxForm } from 'redux-form'; 
import * as actions from '../../actions'; 
import validate from './validate'; 

class FormGlobalInformations extends Component { 
    componentWillMount() { 
     const fakeAccountId = '?accountId=0012400000oAMhY'; 
     this.props.actions.fetchAccount(fakeAccountId); 
    } 

    componentDidMount() { 
     if (this.props.account) { 
      this.props.initialize({ 
       companyName: this.props.account.companyName, 
       typologie: this.props.account.typologie, 
       phone: this.props.account.phone 
      }); 
     } 
    } 

    componentWillUnmount() { 
     const fakeAccountId = '?accountId=0012400000oAMhY'; 
     this.props.actions.updateAccount(fakeAccountId, this.props.form.Information.values); 
    } 

    render() { 
     const { handleSubmit } = this.props; 
     return (
      <form onSubmit={handleSubmit}> 
        <Field 
         label="Nom de l'établissement" 
         name="companyName" 
         type="text" 
         className="form-group" 
         component={this.renderFields} 
        /> 
        <Field 
         label="Type d'établissement : " 
         name="typologie" 
         component={this.renderSelect} 
         className="form-group" 
        /> 
        <Field 
         label="Votre numéro de téléphone de contact" 
         name="phone" 
         type="number" 
         className="form-group" 
         component={this.renderFields} 
        /> 
        <button type="submit" className="btn btn-tiller-full btn-tiller-right">Suite</button> 
      </form> 
     ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
     account: state.account, 
     form: state.form 
    } 
} 

function mapDispatchToProps(dispatch) { 
    return { 
     actions: bindActionCreators(actions, dispatch) 
    } 
} 

FormGlobalInformations = connect(mapStateToProps, mapDispatchToProps)(FormGlobalInformations); 

FormGlobalInformations = reduxForm({ 
    form: 'Information', 
    destroyOnUnmount: false, 
    validate 
})(FormGlobalInformations); 

export default FormGlobalInformations; 

(Die nächste Schritt Form Komponente ist das gleiche, so holen Daten I und I onmount auf Aushänge aktualisieren). Hier

ist die index.js Datei:

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { BrowserRouter, Route, Switch } from 'react-router-dom'; 
import { createStore, applyMiddleware } from 'redux'; 
import logger from 'redux-logger'; 
// import ReduxThunk from 'redux-thunk'; 
import { all } from 'redux-saga/effects'; 

import createSagaMiddleware from 'redux-saga'; 
import reducers from './reducers'; 

// Components 
import Informations from './components/Informations/Informations'; 
import Navigation from './components/Navigation/Navigation'; 
import Header from './components/Navigation/Header'; 

import { accountListener } from './services/account/saga'; 

function* RootListener() { 
    yield all([ 
     accountListener() 
    ]); 
} 

const sagaMiddleware = createSagaMiddleware(); 
const store = createStore(
    reducers, 
    applyMiddleware(sagaMiddleware) 
); 

sagaMiddleware.run(RootListener); 

ReactDOM.render(
    <Provider store={store}> 
     <BrowserRouter> 
      <div> 
       <Header /> 
       <Navigation /> 
       <Switch> 
        <Route path="/informations" component={Informations} /> 
       </Switch> 
      </div> 
     </BrowserRouter> 
    </Provider>, 
    document.querySelector('.container-fluid') 
); 

Hier ist der Fehler, die ich habe, wenn ich versuche zu aktualisieren: enter image description here

Und ich habe eine OPTIONS Anfrage ...

Jemand könnte helfen?

+1

Vielleicht ist ein CORS und Webserver Problem und kein ein Kunde? Ich denke an CORS, weil Sie hier OPTIONEN haben. Beachten Sie, dass bei einigen Webservern (z. B. nginx) HTTP-Verb wie OPTIONS konfiguriert werden müssen –

Antwort

1

Aktualisieren (PUT) Aktion von der API.

Und ich habe eine Anfrage OPTIONEN ...

Die meisten wahrscheinlich, dass Problem ist nicht abhängig von redux-saga, weil Fehler innerhalb in axios Aufruf erfolgt. Vermutete Vorbedingungen mit PUT Verb wirkt sich zwingend OPTIONS Preflight-Abfrage, die verfügbaren CORS Politik für Anfrage Herkunft zurückgibt. Es ist obligatorisch, weil von PUT ist State-Ändern Verb, so HTTP-Header, wie in GET -Requests, ist sehr spät zurück, so dass unabhängige Preflight-Abfrage verwendet wird.

mehr hier How to apply CORS preflight cache to an entire domain und hier lesen Why is an OPTIONS request sent and can I disable it?

Simplest Lösung ohne Preflight-Abfrage hier zur Verfügung gestellt: https://stackoverflow.com/a/40373949/7878274

Verwandte Themen