2017-05-09 38 views
1

我是ReactJS的新手。Reactjs提取身份驗證和訪問令牌,無法解析響應

我正在使用Chrome瀏覽器。

我正在嘗試使用ReactJS在頁面中創建登錄。該頁面使用用戶名和密碼很簡單。身份驗證發生在我們的SSO服務器上,意味着我必須使用獲取調用在服務器上發佈數據,並獲得access_token作爲迴應。

問題如下:

我沒有得到控制檯的響應。但是,當我查看開發人員工具的「網絡」選項卡時,可以看到有一個有效的響應,其中包含所有必填字段,其中包括access_token。 現在肯定我應該如何解析這個。

這是因爲fetch是異步調用?

這是我的整個頁面代碼。

P.S:某些代碼沒有得到格式化。

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()這給誤差:Unexpected end of input

回答

2

至於是您的前端爲fetch(…)請求的JavaScript代碼:

mode: 'no-cors' 

刪除。這是您的代碼無法訪問響應的確切原因。

你從未想過要做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"的答案中所述。

無論是或者您需要讓您的服務器的所有者在您的BASE_URL地址配置服務器發送Access-Control-Allow-Origin的響應。


這裏有一個更詳細的解釋:

您的瀏覽器只會讓你的前端JavaScript的服務器你發出請求從跨域請求代碼存取回應明確表示他們選擇加入接收跨源請求,他們通過在響應中發送Access-Control-Allow-Origin響應標頭來完成。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS有更多細節。

瀏覽器是唯一強制限制跨源請求的客戶端,它們只在Web應用程序上執行它們。

這就是爲什麼即使當你看到一個沒有'訪問控制允許來源'標題出現在請求的資源。 Origin ...因此不允許在您的devtools控制檯中訪問消息,您仍然可以訪問devtools中的Network選項卡並查看其中的響應。

這是因爲服務器已發送響應並且瀏覽器已收到響應,但瀏覽器只是拒絕允許您的前端JavaScript代碼訪問響應,因爲發送響應的服務器尚未選擇進入通過發送Access-Control-Allow-Origin響應頭來實現跨源請求。

當你從curl等發出請求時,你可以得到響應的原因是,除了瀏覽器以外的其他客戶端,如果它沒有Access-Control-Allow-Origin響應頭,將拒絕你的代碼訪問響應。但瀏覽器總是會的。

請注意,這些服務器都不會阻止任何請求或拒絕響應任何請求。服務器總是繼續接收請求併發送響應。唯一的區別在於服務器是否在響應中發送了Access-Control-Allow-Origin標題。

+0

非常感謝您使用no-cors和頭文件'Access-Control-Allow-Origin':'*',如果我不使用這些,我會收到錯誤信息。但我的curl命令工作正常,沒有問題,因此我有點困惑,我的前端代碼中缺少什麼。 – artofabhishek

+0

這是我得到的,如果我刪除標題和no-cors「沒有'Access-Control-Allow-Origin'標題出現在請求的資源上,原因'http:// localhost:3000'因此不被允許訪問。一個不透明的響應滿足你的需求,設置請求的模式爲'no-cors'來取消禁用CORS的資源,但是curl是好的,沒有問題 – artofabhishek

+0

所以是的問題是BASE_URL服務器沒有發送Access-Control-Allow-Origin響應頭我更新了上面的答案以添加更長的解釋,它在curl中工作的原因是curl並不會根據它是否找到Access- Control-Allow-Origin響應頭,但是瀏覽器可以。 – sideshowbarker