2017-05-09 11 views
1

저는 ReactJS를 처음 사용했습니다.응답을 구문 분석 할 수없는 인증 및 액세스 토큰에 대한 패치가있는 Reactj

Chrome 브라우저를 사용하고 있습니다.

ReactJS를 사용하여 로그인 페이지를 만들려고합니다. 이 페이지는 사용자 아이디와 비밀번호로 간단합니다. SSO 서버에서 인증이 발생합니다. 즉, fetch 호출을 사용하여 서버에 데이터를 게시하고 access_token을 응답으로 받아야합니다.

문제는 다음과 같습니다 : 콘솔에서

내가지고 있지 않다 응답. 그러나 개발자 도구의 네트워크 탭을 보면 access_token을 비롯한 모든 필수 입력란에 유효한 응답이 있음을 알 수 있습니다. 이제 이것을 어떻게 파싱해야합니까?

fetch은 비동기 호출이기 때문에입니까?

여기 내 전체 페이지 코드입니다.

피씨 : 일부 코드가 포맷되지 않습니다. Unexpected end of input :

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; 

나는이 같은 오류를 제공 response.json()을 시도했다.

mode: 'no-cors' 

가 제거 :

답변

2

는 지금까지 fetch(…) 요청에 대한 자바 스크립트 코드 프론트 엔드입니다. 그것이 코드가 응답에 액세스 할 수없는 정확한 이유입니다.

절대로 원하지 않는 경우 mode: "no-cors". 실제로 수행하는 유일한 일은 브라우저에 알려주는 것입니다. 프론트 엔드 JavaScript 코드가이 요청의 응답에 액세스하지 못하도록하십시오..

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

해당 줄도 역시 제거하십시오. Access-Control-Allow-Origin응답 헤더입니다. 요청으로 보내지 않으려 고합니다. 유일한 효과는 브라우저가 프리 플라이트를하도록 트리거하는 것입니다.

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

난 당신이 mode: 'no-cors'을 시도하고 요청에 Access-Control-Allow-Origin을 보내는 이유는 이전에 그없이 요청을 시도한다는 것을 추측하고있어 당신은 응답 말하는 브라우저 콘솔에서 오류 메시지를 받았습니다 부족한 Access-Control-Allow-Origin.

그렇다면 프론트 엔드 JavaScript 코드를 변경하여 해결할 수있는 방법은 없습니다. 단, 답변을 "No 'Access-Control-Allow-Origin' header is present on the requested resource"에 요약 된대로 프록시를 통해 요청하도록 코드를 변경해야합니다.

응답이 Access-Control-Allow-Origin 인 서버를 구성하려면 서버의 소유자를 BASE_URL 주소로 가져 가야합니다.


는 여기에 더 이상 설명입니다 :

에만 출처 간 요청에서 코드 액세스 응답이 서버는 요청을하고 자바 스크립트 프론트 엔드를하게됩니다 브라우저가 명시 적으로에 탈퇴하고 표시하기 위해

응답에 Access-Control-Allow-Origin 응답 헤더를 전송하여 교차 원 요청을 수신합니다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS 자세한 내용이 있습니다.

브라우저는 출처 크로스 요청에 대한 제한을 적용하는 유일한 클라이언트이며 웹 응용 프로그램에서만 브라우저를 시행합니다.

이 표시된 경우에도 그렇습니다. 요청한 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. Origin ... 따라서 devtools 콘솔에 액세스 메시지가 허용되지 않으면 devtools의 네트워크 탭으로 이동하여 응답을 볼 수 있습니다.

서버가 응답을 보내고 브라우저가 응답을 받았기 때문에 브라우저가 프런트 엔드 JavaScript 코드가 응답을 보내는 서버가 응답하지 않기 때문에 응답에 액세스하는 것을 거부하기 때문입니다 응답 헤더를 Access-Control-Allow-Origin으로 전송하여 교차 출처 요청

curl 등에서 요청을 할 때 응답을 잘받을 수있는 이유는 응답 헤더가 Access-Control-Allow-Origin이 아닌 경우 브라우저가 응답하지 않고 브라우저가 응답하지 않을 수 없기 때문입니다. 그러나 브라우저는 항상 그렇게 할 것입니다.

그리고 서버가 모든 요청을 차단하거나 거부하는 것은 아닙니다. 서버는 항상 요청을 받고 응답을 보냅니다. 유일한 차이점은 서버가 응답에 Access-Control-Allow-Origin 헤더를 전송하는지 여부입니다.

+0

고마워요. 당신은 no-cors와 헤더 'Access-Control-Allow-Origin'의 사용면에서 '*'이고, 사용하지 않으면 오류가 발생합니다. 하지만 내 컬 명령은 문제가 없으므로 아무런 문제가 없으므로 프런트 엔드 코드에서 빠져있는 부분이 조금 혼란 스럽습니다. – artofabhishek

+0

헤더와 no-cors를 제거하면 얻을 수 있습니다 "No 'Access-Control-Allow-Origin'헤더가 요청 된 리소스에 존재합니다. 'http : // localhost : 3000'은 액세스가 허용되지 않습니다. 불투명 한 응답이 사용자의 요구에 부합하고 요청 모드를 'no-cors'로 설정하여 CORS를 비활성화 한 상태에서 리소스를 가져 오지 만 문제가되지는 않습니다. – artofabhishek

+0

그래, 문제는 BASE_URL 서버가 Access Control-Allow-Origin 응답 헤더. 더 긴 설명을 추가하기 위해 위의 대답을 업데이트했습니다. 컬링에서 작동하는 이유는 컬링이 Access-Control-Allow-Origin 응답 헤더를 찾았는지 여부에 따라 동작을 변경하지 않기 때문입니다. Control-Allow-Origin 응답 헤더. 그러나 브라우저는 허용합니다. – sideshowbarker