2017-05-09 3 views
1

Ich bin ziemlich neu zu ReactJS.Reactjs mit Fetch für Auth und Zugriff Token, nicht in der Lage, Antwort zu analysieren

Ich verwende Chrome Browser.

Ich versuche, die Anmeldeseite mit ReactJS zu erstellen. Die Seite ist einfach mit Benutzer-ID und Passwort. Die Authentifizierung findet auf unserem SSO-Server statt. Das bedeutet, dass ich Daten auf dem Server mithilfe von fetch call posten muss und access_token als Antwort erhalten muss.

Das Problem ist, wie folgt:

Ich bin nicht Antwort in der Konsole zu bekommen. Wenn ich jedoch die Registerkarte "Netzwerk" in den Entwicklertools betrachte, kann ich sehen, dass es eine gültige Antwort mit allen erforderlichen Feldern gibt, einschließlich access_token darin. Jetzt sicher, wie soll ich das analysieren.

Ist dies, weil fetch Async-Aufruf ist?

Hier ist mein gesamter Seitencode.

S.: Ein Teil des Codes wird nicht formatiert.

import React, {Component} from 'react'; 
import '../App/App.css'; 
import {FormGroup, FormControl, InputGroup} from 'react-bootstrap'; 

class Auth extends Component { 


    constructor(props) { 
     super(props); 
     this.state = { 
      userid: '', 
      password: '', 
      accessToken: '' 
     } 
    } 

    submit() { 
     console.log('state', this.state); 
     const BASE_URL = 'MY SSO URL'; 
     const params = { 
      'grant_type': 'password', 
      'username': this.state.userid, 
      'password': this.state.password, 
      'client_secret': 'secred', 
      'client_id': 'client_id', 
     }; 
     const formData = new FormData(); 
     for (let p in params) { 
      formData.append(p, params[p]); 
     } 
     const headers = { 
      'Access-Control-Allow-Origin': '*' 
     }; 
     const request = { 
      method: 'POST', 
      headers: headers, 
      body: formData, 
      mode: 'no-cors' 
     }; 

     fetch(BASE_URL, request) 
      .then((response) => response.text()) 
      .then((responseText) => { 
       console.log('text',responseText); 
      }) 
      .catch((error) => { 
       console.warn(error); 
      }); 
     console.log('all done'); 
    } 

    render() { 
     return (
      <div className="login"> 
       <div className="legend">Signin</div> 
       <FormGroup> 
        <InputGroup> 
         <div className="input"> 
          <FormControl 
           type="text" 
           placeholder="Enter User Id or email" 
           onChange={event => this.setState({userid: event.target.value})} 
           onKeyPress={ 
            event => { 
             if (event.key === 'Enter') { 
              this.submit() 
             } 
            }} 
          /> 
         </div> 
         <div className="input"> 
          <FormControl 
           type="password" 
           placeholder="enter password" 
           onChange={event => { 
            console.log(event.target.value) 
            this.setState({password: event.target.value}) 
           }} 
           onKeyPress={ 
            event => { 
             if (event.key === 'Enter') { 
              this.submit() 
             } 
            }} 
          /> 
         </div> 
         <FormControl 
          type="submit" 
          onClick={() => this.submit()} 
         /> 
        </InputGroup> 
       </FormGroup> 
      </div> 
     ) 
    } 
} 
export default Auth; 

Ich versuchte response.json() dies gibt Fehler wie: Unexpected end of input.

Antwort

2

Wie weit Frontend JavaScript-Code für die fetch(…) Anfrage:

mode: 'no-cors' 

dass entfernen. Das ist der genaue Grund, warum Ihr Code nicht auf die Antwort zugreifen kann.

Sie wollen nie, jemals mode: "no-cors" tun. Die einzige Sache, die tatsächlich tut, ist, dem Browser zu sagen, Lassen Sie nie meinen Frontend-JavaScript-Code die Antwort von dieser Anforderung zugreifen.

const headers = { 
    'Access-Control-Allow-Origin': '*' 
}; 

Entfernen Sie diese Zeilen auch. Access-Control-Allow-Origin ist eine Antwort Header. Sie möchten es nie in einer Anfrage senden. Der einzige Effekt ist, dass ein Browser eine Preflight-Funktion auslöst.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

Ich vermute, dass der Grund, warum Sie mode: 'no-cors' und Senden Access-Control-Allow-Origin in der Anfrage mögen, ist, dass Sie früher die Anfrage ohne denjenigen versucht und man bekam eine Fehlermeldung in der Konsole Browser an, dass die Antwort sagen fehlte Access-Control-Allow-Origin.

Wenn dies der Fall ist, gibt es keine Möglichkeit, das zu ändern, indem Sie Änderungen an Ihrem Frontend-JavaScript-Code vornehmen, außer indem Sie Ihren Code so ändern, dass die Anforderung über einen Proxy erfolgt, wie in der Antwort unter "No 'Access-Control-Allow-Origin' header is present on the requested resource" beschrieben.

Entweder das oder Sie müssen den Besitzer des Servers an Ihre BASE_URL Adresse, um den Server zu konfigurieren, senden Sie die Access-Control-Allow-Origin in seinen Antworten.


Hier ist eine längere Erklärung:

Ihr Browser nur Frontend lassen JavaScript-Code Zugriff Antworten von Cross-Origin-Anfragen, wenn die Server, um die Anfragen sind zu machen explizit anzuzeigen, sie entscheiden sich in zu Cross-Ursprungs-Anfragen erhalten, die sie tun, indem sie den Antwortkopf Access-Control-Allow-Origin in ihren Antworten senden.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS hat weitere Details.

Browser sind die einzigen Clients, die Beschränkungen für ursprungsübergreifende Anforderungen erzwingen und sie nur in Webanwendungen erzwingen.

Deshalb, auch wenn Sie eine Nein 'Access-Control-Allow-Origin' Header ist auf der angeforderten Ressource vorhanden. Origin ... ist daher der Zugriff auf die Nachricht in Ihrer Devtools-Konsole nicht gestattet. Sie können dennoch in den Devtools zur Registerkarte Netzwerk wechseln und dort die Antwort anzeigen.

Das ist, weil der Server die Antwort gesendet hat und der Browser sie erhalten hat, aber der Browser verweigert es gerade Ihrem Frontend-JavaScript-Code, auf die Antwort zuzugreifen, da der Server die Antwort nicht aktiviert hat Cross-Origin-Anfragen durch Senden des Antwortkopfs Access-Control-Allow-Origin.

Der Grund, warum Sie die Antwort erhalten, wenn Sie die Anforderung von curl usw. stellen, ist, dass kein anderer Client als Browser den Zugriff auf die Antwort verweigern wird, wenn der Antwortkopf Access-Control-Allow-Origin fehlt. Aber Browser werden immer.

Und beachten Sie, dass in keinem von denen der Server blockiert oder weigert, auf Anfragen zu reagieren. Der Server empfängt immer nur Anfragen und sendet Antworten. Der einzige Unterschied besteht darin, ob der Server den Header Access-Control-Allow-Origin in der Antwort sendet oder nicht.

+0

Dank und Sie sind genau das Richtige in Bezug auf die Verwendung von nicht-cors und Header ‚Access-Control-Allow-Origin‘: ‚*‘ und wenn ich diese nicht verwende ich Störung erhalte. Aber mein Curl-Befehl funktioniert gut, keine Probleme, daher bin ich etwas verwirrt, was in meinem Front-End-Code fehlt. – artofabhishek

+0

Dies ist, was ich bekomme, wenn ich Kopfzeile und no-cors entfernen "Nein 'Access-Control-Allow-Origin' Header ist auf der angeforderten Ressource vorhanden. Ursprung 'http: // localhost: 3000' ist daher nicht erlaubt eine undurchsichtige Antwort dient Ihren Bedürfnissen, stellen Sie den Modus der Anfrage zu ‚no-cors‘ die Ressource mit CORS deaktiviert zu holen. Aber Locke ist alles gut, es gab keine Probleme. – artofabhishek

+0

Also ja das Problem ist, dass der BASE_URL Server nicht sendet die Access-Control-Allow-Origin-Antwort-Header Ich habe die obige Antwort aktualisiert, um eine längere Erklärung hinzuzufügen. Der Grund, warum es in curl funktioniert, ist, dass curl sein Verhalten nicht ändert, je nachdem, ob es das Access-Steuerelement findet oder nicht. Control-Allow-Origin Antwortheader, aber Browser tun dies. – sideshowbarker

Verwandte Themen