【问题标题】:Fetch fails on consecutive invocations Reactjs连续调用 Reactjs 获取失败
【发布时间】:2020-12-02 06:49:19
【问题描述】:

所以我是 Javascript 和 React 的新手,我正在尝试编写一个简单的登录页面,该页面获取登录表单数据并向我创建的 Django api 发送登录请求。然后 api 应该返回一个 200 状态或 401 的 HttpResponse。我在 api 中启用了 CORS,以便它们可以相互通信。

我发现,使用正确的登录信息,服务器启动后第一次尝试获取成功,但连续登录尝试总是失败,并在浏览器控制台中显示“TypeError: Failed to fetch”。

我的 Django api 函数:

# path 'login/'
def login_user(request):
    login_attempt = json.loads(request.body.decode('utf-8'))
    try:
        user = models.User.objects.get(email=login_attempt['email'],
                                   password=login_attempt['password'])
    except models.User.DoesNotExist:
        user = None

    if user is not None:
        return HttpResponse('Login Success', status=200)

    return HttpResponse('Unauthorised', status=401)

登录.js:

class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: '',
        };

        this.handleEmailChange = this.handleEmailChange.bind(this);
        this.handlePasswordChange = this.handlePasswordChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleResponse = this.handleResponse.bind(this);
    }

    handleEmailChange(event) {
        this.setState({email: event.target.value})
    }

    handlePasswordChange(event) {
        this.setState({password: event.target.value})
    }

    handleResponse(res) {
        if (res.ok) {
            alert('Login Successful!');
            this.props.updateTheUser(this.state.email);
        }
        else if (res.status === 401) {
            alert('Wrong Username or Password');
        }        
    }

    sendLoginRequest(data) {
        fetch('http://localhost:8000/login/', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json'},
            body: data,
        })
        .then(this.handleResponse)
        .catch(function(error) {
            alert('Server error, please try again.');
            console.error(error);
        });
    }

    handleSubmit(event) {
        const data = `{"email": "${this.state.email}", "password": "${this.state.password}"}`
        this.sendLoginRequest(data);
    }

用户.js:

class User extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            isLoggedIn: false
        }

        this.updateUser = this.updateUser.bind(this);
    }

    updateUser(email) {
        console.log(`Entered User.updateUser, email: ${email}`);
        this.setState({
            email: email,
            isLoggedIn: true
        });
    }

    render() {
        if (this.state.isLoggedIn) {
            return <Dashboard/>
        }

        return <Login updateTheUser={this.updateUser}/>
    }
}

查看浏览器的“网络”选项卡,它显示提取状态为“已取消”,并且可以在屏幕截图here 中看到。 我还附上了请求详细信息herehere 的屏幕截图。

【问题讨论】:

  • 我猜updateTheUser函数码也是需要的。我最初的怀疑是,您可能正在删除发起请求的 DOM 元素。
  • 感谢Mahdi的回复,我也加了updateTheUser功能码

标签: javascript reactjs rest fetch


【解决方案1】:

使用this.render 调用渲染方法是一种不好的做法,它可能会导致意外的行为。

当您使用this.setState设置状态时,组件会自动重新渲染,您无需调用this.render

在极少数情况下,您应该使用forceUpdate()

updateUser(email) {
        console.log(`Entered User.updateUser, email: ${email}`);
        this.setState({
            email: email,
            isLoggedIn: true
        });
}

编辑:不使用 preventDefault 可能会导致问题。看here

 handleSubmit(event) {
    event.preventDefault();
    const data = { email: this.state.email, password: this.state.password };
    this.sendLoginRequest(JSON.stringify(data));
}

我在here 中为您的问题创建了一个 github 存储库。我的代码在我模拟的服务器上正常工作。您可以使用我的代码检查您的服务器,如果它再次无法正常工作,那么您的服务器可能有问题。

【讨论】:

  • 您好,谢谢!我已经删除了this.render,但我仍然遇到间歇性提取失败。我为上下文添加了更多源代码。
  • @a-smith96 我真的不能说你的代码有什么问题。如果您可以创建一个 Codesandbox,请分享其链接,以便我查看。
  • 我在这里创建了一个沙箱codesandbox.io/s/login-attempt-e8h7r。这是我的第一个,所以我不确定它如何连接到我的本地 Django api,如果它有效,请告诉我,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
相关资源
最近更新 更多