Как использовать один и тот же порт для react js и node js?

Собственно, я хочу создать контактную форму на веб-сайте, используя reactjs и nodejs. Я создал форму с помощью React, а для бэкэнда мне нужно подключить узел js, чтобы получить электронное письмо. Но этого не происходит И React, и Node должны работать на одном порте. Я указал прокси как «http: // локальный: 3000» в package.json, но он все равно не работает.

Я привел код реакции как js, так и node js. Пожалуйста, помогите мне решить эту ошибку.

React JS Code

import React, { Component } from "react";
import axios from "axios";

export default class formSection extends Component {
  state = {
    name: "",
    email: "",
    subject: "",
    comment: ""
  };

  handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

 async handleSubmit(e) {
    e.preventDefault()
    const {name, email, subject, comment} = this.state

    const contact = await axios.post('/api/contact', {

        name,
        email,
        subject,
        comment

    })

  };

  render() {
    return (
      <section
        className="wow fadeIn big-section"
        id="section-down"
        style={{ visibility: true }}
      >
        <div className="container">
          <div className="row equalize sm-equalize-auto">
            <div
              className="col-md-6 col-sm-12 col-xs-12 sm-margin-30px-bottom wow fadeInLeft"
              style={{ visibility: true, height: 597 }}
            >
              <div className="padding-fifteen-all bg-light-gray border-radius-6 md-padding-seven-all xs-padding-30px-all height-100">
                <span className="text-extra-dark-gray alt-font text-large font-weight-600 margin-25px-bottom display-block">
                  Ready to get started?
                </span>
                <form id="contact-form" onSubmit={e=>this.handleSubmit(e)} method="POST">
                  <div>
                    <div
                      id="success-contact-form"
                      className="no-margin-lr"
                      style={{ display: true }}
                    />
                    <input
                      type="text"
                      name="name"
                      id="name"
                      value={this.state.name}
                      placeholder="Name*"
                      className="border-radius-4  medium-input"
                      onChange={this.handleChange}
                    />
                    <input
                      type="text"
                      name="email"
                      value={this.state.email}
                      id="email"
                      placeholder="E-mail*"
                      className="border-radius-4  medium-input"
                      onChange={this.handleChange}
                    />
                    <input
                      type="text"
                      name="subject"
                      id="subject"
                      value={this.state.subject}
                      placeholder="Subject"
                      className="border-radius-4  medium-input"
                      onChange={this.handleChange}
                    />
                    <textarea
                      name="comment"
                      id="comment"
                      value={this.state.comment}
                      placeholder="Your Message"
                      rows="5"
                      className="border-radius-4  medium-textarea"
                      onChange={this.handleChange}
                    />
                    <button
                      id="contact-us-button"
                      type="submit"
                      className="btn btn-small border-radius-4 btn-dark-gray"

                    >
                      send message
                    </button>
                  </div>
                </form>
              </div>
            </div>
            <div
              className="col-md-6 col-sm-12 col-xs-12 last-paragraph-no-margin wow fadeInRight"
              style={{ visibility: true, height: 597 }}
            >
              <div className="padding-ten-all bg-light-gray border-radius-6 md-padding-seven-all xs-padding-30px-all height-100 sm-text-center">
                <img
                  src="images/about-img1.jpg"
                  alt=""
                  className="border-radius-6 margin-35px-bottom xs-margin-30px-bottom"
                  data-no-retina=""
                />
                <span className="text-large font-weight-600 alt-font text-extra-dark-gray margin-5px-bottom display-block">
                  Let's plan for a new project?
                </span>
                <p>
                  Lorem Ipsum is simply dummy text of the printing and
                  typesetting industry, Lorem Ipsum has been the standard dummy
                  text.
                </p>
                <a
                  href="about-us-modern.html"
                  className="btn btn-dark-gray btn-small text-extra-small border-radius-4 margin-25px-top"
                >
                  About Company
                </a>
              </div>
            </div>
          </div>
        </div>
      </section>
    );
  }
}

Код узла JS

const express = require('express');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer');
const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));

app.post('/api/contact', (req, res) => {

console.log(req.body);

});




const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {

    console.log(`server listening in port ${PORT}`);

})

хотите, чтобы вы запускали реакцию и узел на одном порте?

Mohmmad Ebrahimi Aval 31.10.2018 14:16

Ага, порт 3000! Я пробовал, но не работал. Не могли бы вы помочь?

Ameen 31.10.2018 14:19

React не работает на собственном порту. Он работает на Node, который работает на порту 3000. Непонятно, в чем ваша проблема. Каким образом "не работает"? Где вы вводите React в свою индексную страницу?

jmargolisvt 31.10.2018 14:22

вы можете сделать это ТОЛЬКО при использовании одного сервера nodejs для реагирования на SSR и сервер API. это означает, что вы не можете использовать такие инструменты, как create-response-app. вы пользуетесь инструментами или чисто реагируете?

Mohmmad Ebrahimi Aval 31.10.2018 14:24

@mihai Создал форму с помощью React (т.е.) Front End. Теперь нужно отправить электронное письмо с помощью сервера node js. Если я запускаю сервер узла, интерфейс не работает. Пожалуйста, проверьте код выше.

Ameen 31.10.2018 14:30

@jmorgolisvt Получение ошибки как «Невозможно GET /» при запуске сервера узла

Ameen 31.10.2018 14:33

@Keith Brewster: да, он работает, но нужно запускать с реакцией js

Ameen 31.10.2018 14:46
6
7
14 281
6

Ответы 6

Я предполагаю, что вы используете приложение create-response-app и добавили конфигурацию прокси в package.json.

Приложение Create-response-app запускается на порту 3000, поэтому ваш экспресс-сервер должен запускаться на любом другом порту (НЕ 3000), затем вы меняете конфигурацию прокси-сервера на этот порт.

Т.е. const PORT = process.env.PORT || 5000; Затем измените конфигурацию прокси-сервера frontend package.json, например "proxy": "http: // локальный: 5000"

Обратите внимание, что это следует использовать только для разработки. Для производства: соберите пакет и используйте экспресс для обслуживания статического содержимого из папки сборки.

Я сделал это соответственно, но получаю сообщение об ошибке «Не могу GET /».

Ameen 31.10.2018 14:32

@Ameen проверьте журнал серверного процесса. там сказано "сервер слушает порт 5000"? Я спрашиваю, раз я только что сделал все эти шаги, и все работает нормально.

Sim Dim 31.10.2018 14:34

@ Амин, подожди, как ты это проверяешь?

Sim Dim 31.10.2018 14:35

да, есть то же сообщение о состоянии, что и «сервер прослушивает порт 5000». Никакой ошибки в этом

Ameen 31.10.2018 14:36

Используя редактор кода Visual Studio, он показывает статус и использование nodemon для перезапуска сервера.

Ameen 31.10.2018 14:39

@Ameen Я имею в виду, как вы получаете "Не могу ПОЛУЧИТЬ /"? Перейдите к локальный: 3000 и нажмите "Отправить", затем проверьте консоль vscode.

Sim Dim 31.10.2018 14:41

Тот же статус "сервер прослушивает порт 3000"

Ameen 31.10.2018 14:47

@Ameen, бэкэнд должен быть запущен на 5000, а в журналах должно быть указано «сервер прослушивает порт 5000», а интерфейс должен быть запущен на 3000 (с использованием yarn или npm start). Затем вы переходите к localhost: 3000 и нажимаете кнопку отправки, после чего тело запроса должно появиться в серверной консоли.

Sim Dim 31.10.2018 15:09

если вы используете такие инструменты, как create-react-app, ответ будет 'не могу этого сделать', потому что вы не можете редактировать сервер nodejs, а на другой стороне в производственном режиме проект сборки create-react-app и не имеете ни одного сервера nodejs в производстве.

но когда вы разрабатываете реакцию как чистую и SSR, вы можете получить доступ к серверу nodejs и можете это сделать.

см. это для реакции SSR:

https://medium.freecodecamp.org/demystifying-reacts-server-side-render-de335d408fe4

Кто-то отметил опубликованный мной вопрос как возможный дубликат. Не уверен, что это применимо, так как моей целью было бы запустить 2 сценария (отдельные файлы) в одном порту. Это возможно? stackoverflow.com/questions/62155391/…

Jorge Mauricio 02.06.2020 21:26

Вы не можете добиться этого с помощью подхода, которому следуете.

Почему?

вы пытаетесь запустить два разных сервера на одном порту (сервер узла и сервер webpackdev)

Любая альтернатива?

да, в соответствии с вашим требованием вам не нужен отдельный сервер для внешнего интерфейса, вы можете использовать его как статические файлы.

Как?

  1. создайте свое приложение (для приложения create-response-app npm run build)

  2. скопируйте все содержимое папки build в новую папку (скажем, public) в своем экспресс-приложении.

  3. теперь добавьте ниже в код js вашего узла (для обслуживания статических файлов):

    app.use('/', express.static('./public'));

а теперь посетите http://localhost:3000

есть ли у этого недостатки? за и против? меня устраивает. Это безопасно в производстве?

alfian5229 27.12.2019 04:00

Я думаю, что в производстве вам нужно указать в package.json для сборки react-app, чем копировать контент из сборки в папку public, возможно, используя действие github, вы можете добиться этого

mirsahib 03.01.2021 18:59

Как справиться с обновлением в этом случае. Скажем, у меня есть конечная точка / схема, я ввел ее в браузере и обновил. Но эта конечная точка попадет в заднюю часть (узел), и будет выдана ошибка как Cannot GET / schema. Как перенаправить в общую папку, если конечная точка отсутствует в API.

ARods 31.03.2021 08:18

Решение, если вы используете webpack / dev-server

package.json файл:

"proxy": "http://localhost:5000",

Если вы используете dev-sever с webpack, то в webpack.cofing.js добавьте это:

    proxy: {
        '/api': "http://localhost:5000",
    },

backend.js файл:

const server = http.createServer((req, res) => {
  res.write('Hello World!');
  res.end();
});

server.listen({
  host: 'localhost',
  port: 5000,
});

Когда вы открываете сайт, введите: localhost:8080 (или по умолчанию для вас), а затем, когда вы захотите открыть свой сервер node.js, просто добавьте /api в свой URL-адрес, он должен выглядеть так: localhost:8080/api.

Я нашел решение Как начать реагировать и приложение nodejs на одном порту. пожалуйста, откройте ссылку git https://github.com/chandrakant1990/react-node-express-app-on-same-port

Возьмите клон этого репо. В Client forlder просто запустите команду npm install затем запустите приложение sh start.sh

Ваше приложение будет запущено на localhost: 3000

Для изменений на стороне клиента Вам не нужно повторно перезапускать приложение. Для изменений на стороне сервера перезапустите приложение.

Более подробно вы можете посмотреть видео https://youtu.be/AiEC2_8mIIY

Единственный способ, которым, как мне кажется, лучше всего добиться с помощью одного и того же порта, - это использовать рендеринг на стороне сервера. вы можете узнать больше об этом здесь

https://www.freecodecamp.org/news/demystifying-reacts-server-side-render-de335d408fe4/

Другие вопросы по теме