Javascript Reactjs使用获取身份验证和访问令牌,无法分析响应

Javascript Reactjs使用获取身份验证和访问令牌,无法分析响应,javascript,reactjs,authentication,cors,fetch-api,Javascript,Reactjs,Authentication,Cors,Fetch Api,我是个新手 我正在使用Chrome浏览器 我正在尝试使用ReactJS创建登录页面。页面很简单,带有用户id和密码。身份验证发生在我们的SSO服务器上,这意味着我必须使用fetch调用在服务器上发布数据,并获取访问令牌作为响应 问题如下: 我在控制台中没有得到响应。但是,当我查看开发人员工具上的网络选项卡时,我可以看到有一个有效的响应,其中包含所有必需字段,包括访问令牌。 现在确定我应该如何解析这个 这是因为fetch是异步调用吗 这是我的整个页面代码 附言:有些代码没有格式化 import R

我是个新手

我正在使用Chrome浏览器

我正在尝试使用ReactJS创建登录页面。页面很简单,带有用户id和密码。身份验证发生在我们的SSO服务器上,这意味着我必须使用fetch调用在服务器上发布数据,并获取访问令牌作为响应

问题如下:

我在控制台中没有得到响应。但是,当我查看开发人员工具上的网络选项卡时,我可以看到有一个有效的响应,其中包含所有必需字段,包括访问令牌。 现在确定我应该如何解析这个

这是因为fetch是异步调用吗

这是我的整个页面代码

附言:有些代码没有格式化

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。这会导致错误:输入意外结束。

关于fetch…请求的前端JavaScript代码:

去掉那个。这正是代码无法访问响应的原因

你永远不想做模式:没有cors。实际上唯一要做的就是告诉浏览器,永远不要让我的前端JavaScript代码访问这个请求的响应

把那些线也移走。访问控制允许源是一个响应头。你永远不想在请求中发送它。唯一的效果就是触发浏览器进行飞行前的操作

我猜您尝试“无cors”模式并在请求中发送访问控制允许源代码的原因是您之前尝试了没有这些模式的请求,并且在浏览器控制台中收到一条错误消息,表示响应缺少访问控制允许源代码

如果是这样的话,您就无法通过更改前端JavaScript代码来规避这一问题,除非您将代码更改为通过代理发出请求,如上的回答中所述

或者您需要在您的基本URL地址获取服务器的所有者,以配置服务器以在其响应中发送访问控制允许源

这里有一个较长的解释:

当您发出请求的服务器明确表示他们选择接收跨源请求时,您的浏览器只允许前端JavaScript代码访问来自跨源请求的响应,这是通过在响应中发送access Control Allow origin response标头实现的

有更多的细节

浏览器是唯一对跨源请求实施限制的客户端,它们只对web应用程序实施限制

这就是为什么即使在您看到请求的资源上不存在“Access Control Allow Origin”头的原因。因此,在您的devtools控制台中不允许访问Origin…消息,您仍然可以转到devtools中的Network选项卡并在那里查看响应

这是因为服务器已发送响应,而浏览器已接收到响应,但浏览器只是拒绝允许前端JavaScript代码访问响应,因为发送响应的服务器尚未通过发送访问控制允许源响应头选择跨源请求

当您从curl等发出请求时,可以很好地得到响应的原因是,如果响应缺少访问控制allow Origin响应头,那么除了浏览器之外,没有任何客户端会拒绝允许您的代码访问响应。但浏览器总是会


请注意,在所有这些情况下,服务器都不会阻止或拒绝响应任何请求。服务器始终只接收请求和发送响应。唯一的区别在于服务器是否在响应中发送Access Control Allow Origin标头。

谢谢,您在使用no cors和标头“Access Control Allow Origin”方面非常成功:“*”,如果我不使用这些,我就会出错。但是我的curl命令工作正常,没有问题,因此我有点困惑我的前端代码中缺少什么。如果我删除了头,并且请求的资源上没有cors没有“Access Control Allow Origin”头,这就是我得到的结果。因此,不允许“源”访问。如果不透明响应满足您的需要,请将请求的模式设置为“no cors”,以获取禁用cors的资源。但是curl很好,没有问题。所以问题是BASE_URL服务器没有发送访问控制允许源响应头。我更新了上面的答案,添加了更长的解释。它在curl中工作的原因是curl不会根据是否找到accesscontrolalloworigin响应头来更改其行为。但浏览器确实如此。
mode: 'no-cors'
const headers = {
    'Access-Control-Allow-Origin': '*'
};