简体   繁体   English

类型错误:无法在 reactjs 登录页面中获取

[英]TypeError: Failed to fetch in reactjs login page

I've been trying to create a login page but I'm getting this error called "TypeError: Failed to fetch" .我一直在尝试创建一个登录页面,但我收到了一个名为"TypeError: Failed to fetch" I have no idea where I did wrong, I checked a few StackOverflow answers, like I tried adding the event.preventdefault as I saw in one of StackOverflow answer but that didn't help.我不知道我哪里做错了,我检查了一些 StackOverflow 的答案,就像我在 StackOverflow 的一个答案中看到的那样尝试添加event.preventdefault ,但这没有帮助。

Could someone point out the part where I'm doing wrong?有人可以指出我做错的部分吗?

Also note: it's working fine in postman with the API.另请注意:它在邮递员中使用 API 工作正常。 I tried the same email and password there and it's working fine in postman but getting the error with the react website.我在那里尝试了相同的电子邮件和密码,它在邮递员中工作正常,但在 react 网站上出现错误。

import React, { Component } from "react";
class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
    this.onchange = this.onchange.bind(this);
  }

  onchange(e) {
    this.setState({ [e.target.name]: e.target.value });
    console.log(this.state);
  }

  performLogin = async event => {
    event.preventDefault();
    console.log("button clicked");
    var body = {
      password: "this.state.password",
      email: "this.state.email"
    };

    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: JSON.stringify(body)
    };

    const url = "/api/authenticate";

    try {
      const response = await fetch(url, options);
      const result = await response.json();
      console.log(result);
      console.log(`login successful`);
      window.alert("login succesful");
    } catch (error) {
      console.error(error);
    }
  };

  render() {
    return (
      <div>
        <input type="text" placeholder="emailid" onChange={this.onchange} />
        <br />
        <input
          type="password"
          placeholder="Enter your Password"
          onChange={this.onchange}
        />
        <br />
        <button type="submit" onClick={event => this.performLogin(event)}>
          Submit
        </button>
      </div>
    );
  }
}
export default Login;

one anamoly is that in postman, it accepts only when I post like I've shown below一个异常是在邮递员中,只有当我像下面显示的那样发帖时它才接受

{
    "password":"pass",
    "email":"admin"
}

If I remove the quotes then it gives me bad string error in postman but in codesandbox, the quotes are automatically removed when I save the sandbox.如果我删除引号,那么它会在邮递员中出现错误的字符串错误,但在代码沙箱中,当我保存沙箱时,引号会自动删除。 could it be because of that or is it nothing to worry about?可能是因为那个还是没什么可担心的?

First you need to give your inputs name attribute to be able to correctly update the state onChange like this:首先,您需要提供输入名称属性,以便能够像这样正确更新状态 onChange:

<input type="text" name="email" placeholder="emailid" onChange={this.onchange} /> <br />
<input type="password" name="password" placeholder="Enter your Password" onChange={this.onchange}/>

Secondly, you need to create the request body like this:其次,您需要像这样创建请求正文:

   var body = {
      password: this.state.password,
      email: this.state.email
    };

And lastly, you need to check if fetch response is ok, because in 4xx errors fetch does not give error.最后,您需要检查 fetch 响应是否正常,因为在 4xx 错误中 fetch 不会给出错误。

So with all these changes, your component code must be like this:因此,有了所有这些更改,您的组件代码必须是这样的:

import React, { Component } from "react";
class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
    this.onchange = this.onchange.bind(this);
  }
  onchange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }
  performLogin = async event => {
    event.preventDefault();
    var body = {
      password: this.state.password,
      email: this.state.email
    };
    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: JSON.stringify(body)
    };
    const url = "/api/authenticate";
    try {
      const response = await fetch(url, options);
      const result = await response.json();
      console.log(result);
      if (response.ok) {
        console.log("login successful");
        window.alert("login succesful");
      } else {
        console.log("login failed");
        window.alert("login failed");
      }
    } catch (error) {
      console.error(error);
    }
  };

  render() {
    return (
      <div>
        <input
          type="text"
          name="email"
          placeholder="emailid"
          onChange={this.onchange}
        />
        <br />
        <input
          type="password"
          name="password"
          placeholder="Enter your Password"
          onChange={this.onchange}
        />
        <br />
        <button type="submit" onClick={event => this.performLogin(event)}>
          Submit
        </button>
        <hr />
        State: {JSON.stringify(this.state)}
      </div>
    );
  }
}
export default Login;

But these fixes in react app will not be enough, because codesandbox uses https and login api is using http.但是react app 中的这些修复是不够的,因为codeandbox 使用https 而login api 使用http。 This will give the following error:这将给出以下错误:

Mixed Content: The page at ' https://hkj22.csb.app/Login ' was loaded over HTTPS, but requested an insecure resource 'http://***/api/authenticate'.混合内容:“ https://hkj22.csb.app/Login ”页面已通过 HTTPS 加载,但请求了不安全的资源“http://***/api/authenticate”。 This request has been blocked;此请求已被阻止; the content must be served over HTTPS.内容必须通过 HTTPS 提供。

And only way to resolve this problem seems to use https for the api as described in this answer .解决此问题的唯一方法似乎是使用 https 用于 api,如本答案所述

You can contact api owner to host his api using https.您可以联系 api 所有者使用 https 托管他的 api。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM