【问题标题】:How to fix failure to fetch warning React.js and Node.js如何修复无法获取警告 React.js 和 Node.js
【发布时间】:2022-11-29 18:57:28
【问题描述】:

每次我在我的购买页面上时,一切正常并且更新正常。当我在页面中第一次点击提交时,它会正确更新我的数据库,但不会弹出警报窗口。 => 页面重新呈现并将自身设置为初始视图。如果我留在页面上并提交第二次购买,那么我会收到一个弹出框,提示无法通过 post 方法获取,然后弹出提示框,提示购买成功。即使发生故障,在功能上也没有任何错误。所有数据库文件都是最新的。有人请帮助我不知道我做错了什么。

我的前端 react.js

import React, { useState, useEffect } from 'react';
import { NumberFormat as numberFormat } from '../numberFormat';
export default function Purchase() {
    // user input collection structure
    const [form, setForm] = useState({
        amount: '',
        title: '',
    })
    // user spending limit
    const [limit, setLimit] = useState({
        balance: 0,
        limit: 0,
    })

    useEffect(() => {
        async function getLimit() {
            const response = await fetch(`http://localhost:4000/balance/`);

            if (!response.ok) {
                const message = `An error occured at effect: ${response.statusText}`;
                window.alert(message);
                return;
            }
            const data = await response.json();
            const userBal = data["balance"];
            const userLim = 50 - parseFloat(userBal);
            setLimit({ balance: userBal, limit: userLim });
        }
        getLimit();
        return;

    }, []);

    // Update State Properties
    function updateForm(value) {
        return setForm((prev) => {
            return { ...prev, ...value };
        });
    }
        function validateInput(input){
            input = input * 1000;
            if (input%10 === 0) return false;
            else return true;
        }
    async function onSubmit() {
        // check that amount is valid 
        if (form.title === ''){
            window.alert(`Please Include a Title for the payment`);
            return;
        }
        const bal = parseFloat(limit.balance);
        const lim = parseFloat(limit.limit);
        const amt = parseFloat(form.amount);
        if (amt > lim || amt === 0 || amt === '' || validateInput(amt)){
            window.alert(`Invalid Amount ${form.amount}.\nPlease enter value greater than 0.00 within ${lim}.`);
            return;
        }
        const newPurchase = {
            type: 'purchase',
            amount: form.amount,
            title: form.title,
            balanceToSet: amt + bal
        }

        await fetch(`http://localhost:4000/purchase/add`, {
            method: 'POST',
            mode:'cors',
            headers: {
                'Access-Control-Allow-Origin': '*',
                "Content-Type": 'application/json; charset=UTF-8',
            },
            body: JSON.stringify(newPurchase)
        }
        )
        .then((response) => response.json()).then((data)=> {console.log(data);
        })
            .catch((err) => {
                window.alert(`post fetch error ${err.message}`);
                return;
            });
        window.alert(`Purchase ${form.title} of amount $${form.amount} posted.`);
        return;
    }

    return (
        // Will Display
        <div className='home'>
            {/* Title */}
            <h1 className='hometitle'>
                Make A Purchase
            </h1>
            <div>
                <h1> Your Fizz Balance: {numberFormat(limit.balance)}</h1>
                <h1> Your Fizz Allowance: {numberFormat(limit.limit)}</h1>
            </div>
            {/* Current Allowance */}

            {/* Debt owed to fizz */}

            {/* Make Purchase Form
                If incorrect parameters then show text saying invalid amount below 
                On submission alert shows telling user a purchase of certain amount was made
                render rest of the page */}
            <form onSubmit={onSubmit}>
                <div className="form-group">
                    <label htmlFor='title'>Title:</label>
                    <input
                        type='text'
                        id='name'
                        value={form.title}
                        onChange={(e) => updateForm({ title: e.target.value })}
                    />
                </div>
                <div className="form-group">
                    <label htmlFor="amount">Amount:</label>
                    <input
                        type="text"
                        id="amount"
                        value={form.amount}
                        onChange={(e) => updateForm({ amount: e.target.value })}
                    />
                </div>
                <div>
                    <input
                        type='submit'
                        value='Make Purchase'
                    />
                </div>
            </form>

        </div>
    );
}

我的后端 node.js

const express = require("express");

const purchaseRoutes = express.Router();
const dbo = require("../db/connection");
const { floor } = require('mathjs');
// Add purchase to History Table and update balance in user info
purchaseRoutes.route("/purchase/add").post(
    async function (req, response) {
        let db_connect = dbo.getDb();
        // Writing Purchase to History Table
        let thisPurchase = {
            type: req.body.type,
            amount: parseFloat(req.body.amount),
            title: req.body.title,
            rfndStatus: false,
            date: Date.now()
        };
        let queryParams = { name: "user" };
        // post query contents
        let updatedBalance = {
            $set: {
                balance: floor(req.body.balanceToSet * 1000) / 1000
            }
        };
        const session = db_connect.startSession();
        const transactionDetails = {
            readPreference: 'primary',
            readConcern: { level: 'local' },
            writeConcern: { w: 'majority' }
        }

        try {
            const transactionResults = await session.withTransaction(async () => {
                const userColl = db_connect.db('fizzData').collection('userData');
                const histColl = db_connect.db('fizzData').collection('transHist');

                await userColl.updateOne(queryParams, updatedBalance,{session});
                await histColl.insertOne(thisPurchase,{session});
            }, transactionDetails);
            response.json(transactionResults);
            console.log(transactionResults);
        } catch(e){
            console.log(`transaction failed ${e}`)
        }
         finally {
            await session.endSession();
        }
    });

在 postman 中,我使用相同的标头、url 和正文测试了我的 fetch 调用,我的回应是这样的。

{"ok":1,"$clusterTime":{"clusterTime":{"$timestamp":"7171344646893731861"},"signature":{"hash":"qwfNCLTeYc+/Gr79JghaSuDtZvQ=","keyId":{" low":8,"high":1659459863,"unsigned":false}}},"operationTime":{"$timestamp":"7171344646893731861"}}

我认为这可能是一个 cors 问题,所以我在 chrome 中安装了 cors 扩展并将模式标签添加到标题中。问题不在于 useEffect 中的提取或至少是调用,因为它正确地从数据库中调用了正确的值。

【问题讨论】:

  • 您在第二次尝试保存时会收到哪些警报?您能否在代码中指出出现问题时正在执行的 window.alert 块?
  • @ShubhamWaje 它们按连续顺序弹出,两个窗口警报都接近 onSubmit 函数的末尾。此外,当我检查开发工具中的网络选项卡时,那些发布请求根本不会显示在第一个上。然后在第二个它尝试拨打电话并取消。
  • 我也刚刚对提交进行了一些更改,发现现在根本没有弹出窗口出现,但也没有弹出错误。但是,请求根本没有记录在开发工具的网络选项卡中。我没有设置 .catch,而是设置了 fetch = response,然后如果响应正常,我调用弹出窗口向用户报告成功。
  • 此外,这不会在开发人员工具的“我的网络”选项卡中记录任何后调用。我是一周大的 React 用户,所以我仍然熟悉该语言的语法和属性,但我有理由相信问题出在前端。我认为在获取完成之前购买页面正在渲染或重建。

标签: node.js reactjs mongodb fetch


【解决方案1】:

似乎用户代理不知道表单事件正在处理中。

要解决此问题,请按如下方式修改您的 onSubmit 函数:

async function onSubmit(event) {
    event?.preventDefault();

    // ... rest of  
    // ... of the
    // ... code
        
}

看看它是否有效:)

【讨论】:

    猜你喜欢
    • 2021-09-11
    • 1970-01-01
    • 2020-06-20
    • 2019-03-25
    • 2014-09-18
    • 2018-02-07
    • 2019-08-08
    相关资源
    最近更新 更多