@Bulgar

Ошибка 404 (Not Found) при соединении клиентской и серверной части на React. Что делать?

Сделал форму обратной связи, отдельно сервер клиент работают хорошо. Но когда их объединил на одном хосте при нажатии отправить (заявка обратной связи на почту ) выходит ошибка. Ругается на строку в Hero.jsx const response = await fetch("/api/feedback", {

Серверная часть server.js
const express = require('express'); 
const nodemailer = require('nodemailer'); 

const server = express();


server.use(express.static(__dirname + '/public'));
server.use(express.json());


server.get('/', (req, res) => {
    res.sendFile("public/index.html", { root: __dirname})
})


server.post("/api/feedback", async(req, res) => {
    try {

     const transporter = nodemailer.createTransport({
        host: "smtp.mail.ru",
        port: 465,
        secure: true,
        auth: {
            user: "ya@mail.ru",
            pass: "**********"  
        }
     });   

     const { name, phone, message} = req.body;

     await transporter.sendMail({
        from: "ya@mail.ru",
        to: "ya@mail.ru",
        subject: "Тема письма",
        text: `${name} ${phone} ${message}`,
        html: 
        `
        <p>${name}</p>
        <p>${phone}</p>
        <p>${message}</p>
        `


     });

     return res.status(200).send({
        status: 200,
        message: 'Успешня отправка'
     })

    } catch (e) {
        return res.status(500).send({
            status:500,
            message: 'Ошибка при запросе'
        });
    } 
})


server.listen(5000, () => {

    console.log('listening on port 5000'); 

})


script.js

const FEEDBACK_FORM = document.querySelector('#feedback-form');

function sendFeedback(feedback) {
    fetch("/api/feedback" , {
        method: 'POST',
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(feedback),
    }).then((response)=>response.json()).then(data => {
        console.log(data);
        alert('Успешно');
    }).catch((error) => {
        console.error(error);
        alert('Ошибка');
    });
}

FEEDBACK_FORM.addEventListener('submit', (e) => {
    e.preventDefault();
    const feedbackFormData = new FormData(e.target);
    console.log('feedbackFormData', feedbackFormData);
    const feedback = Object.fromEntries(feedbackFormData);
    console.log('feedback', feedback);

    sendFeedback(feedback);
})


Клиентская часть Hero.jsx

import React, { useState } from "react";
import styles from "./Hero.module.css";
import { getImageUrl } from "../../utils";

export const Hero = () => {
  const [isOpen, setIsOpen] = useState(false);
  const [formData, setFormData] = useState({
    name: "",
    phone: "",
    message: ""
  });

  const openModal = () => {
    setIsOpen(true);
  };

  const closeModal = () => {
    setIsOpen(false);
  };

  const handleCall = () => {
    window.location.href = "tel:**************";
  };

  const handleFormSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await fetch("/api/feedback", {
        method: 'POST',
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify(formData),
      });
      
      if (response.ok) {
        alert('Успешно');
        setFormData({
          name: "",
          phone: "",
          message: ""
        });
      } else {
        alert('Ошибка');
      }
    } catch (error) {
      console.error(error);
      alert('Ошибка');
    }
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((prevData) => ({
      ...prevData,
      [name]: value
    }));
  };

  return (
    <section className={styles.container}>
      <div className={styles.content}>
        <h1 className={styles.title}>*********</h1>
        <p className={styles.description}>
          «Ya» 
        </p>
        <a href="tel:+**********" className={styles.contactBtn} onClick={handleCall}>
          Позвонить
        </a>
        <button onClick={openModal} className={styles.contactBTN}>
          Оставить заявку
        </button>
        {isOpen && (
          <form onSubmit={handleFormSubmit}>
            <input
              type="text"
              name="name"
              value={formData.name}
              onChange={handleChange}
              placeholder="Имя"
            />
            <input
              type="tel"
              name="phone"
              value={formData.phone}
              onChange={handleChange}
              placeholder="Телефон"
            />
            <textarea
              name="message"
              value={formData.message}
              onChange={handleChange}
              placeholder="Сообщение"
            />
            <button type="submit">Отправить</button>
          </form>
        )}
      </div>
      <img
        src={getImageUrl("hero/heroImage.png")}
        alt="Hero image of me"
        className={styles.heroImg}
      />
      <div className={styles.topBlur} />
      <div className={styles.bottomBlur} />
    </section>
  );
};

export default Hero;
  • Вопрос задан
  • 110 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 нояб. 2024, в 00:55
500 руб./за проект
21 нояб. 2024, в 23:30
300000 руб./за проект
21 нояб. 2024, в 22:21
3000 руб./в час