我是ReactJS的新手。
我正在使用Chrome浏览器。
我正在尝试使用ReactJS创建登录页面。页面很简单,包含用户ID和密码。身份验证发生在我们的SSO服务器上,这意味着我必须使用fetch调用在服务器上发布数据并获取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
。
答案 0 :(得分:4)
到目前为止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"上的答案中所述。< / p>
或者您需要让BASE_URL
地址的服务器所有者配置服务器以在其响应中发送Access-Control-Allow-Origin
。
这是一个更长的解释:
当您发出请求的服务器明确表示他们选择接收跨源请求时,您的浏览器只会让您的前端JavaScript代码访问来自跨源请求的响应,而他们通过发送{ {1}}响应中的响应标头。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS有更多详情。
浏览器是唯一对跨源请求实施限制的客户端,它们只在Web应用程序上强制实施。
这就是为什么即使您在请求的资源上看到 No'Access-Control-Allow-Origin'标头也是如此。因此,在您的devtools控制台中不允许访问消息,您仍然可以转到devtools中的“网络”选项卡并在那里查看响应。
那是因为服务器已发送响应并且浏览器已收到响应,但浏览器只是拒绝允许您的前端JavaScript代码访问响应,因为发送响应的服务器没有选择交叉-origin通过发送Access-Control-Allow-Origin
响应标头请求。
当您从curl等处提出请求时,您可以获得响应的原因是,除了浏览器之外,没有其他客户端拒绝允许您的代码在缺少Access-Control-Allow-Origin
响应时访问该响应头。但浏览器总会如此。
请注意,这些都不是服务器阻止或拒绝响应任何请求。服务器始终只是接收请求并发送响应。唯一的区别在于服务器是否在响应中发送Access-Control-Allow-Origin
标头。