Как сделать конечную точку api целевым локальным хостом пользователя при развертывании на Heroku - PullRequest
0 голосов
/ 20 июня 2020

У меня есть этот api, который отлично работает при локальном запуске. Но как только он развернут на Heroku, я получаю ошибку 503, потому что он пытается настроить таргетинг на localhost на сервере Heroku, а не на localhost пользователя. Есть ли способ вместо этого сделать эту цель локальным хостом пользователя?

Интерфейс - это React. Вот код в React, который загружает этот API каждые 5se c.

axiosFunc = () => {
    const { user } = this.props.auth;
    console.log(user);
    axios.get(`api/avaya/${user.id}`).then((res) => console.log(res));
  };

  timer = (time) => {
    const date = new Date(time);
    return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
  };

  componentDidMount() {
    this.axiosFunc();
    this.interval = setInterval(this.axiosFunc, 5000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

, а это API на бэкэнде с express

const router = require("express").Router();
const xml2js = require("xml2js");
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");

router.route("/:id").get(async (req, res) => {
  const user = await User.findById(req.params.id);
  const axios = require("axios");

  axios({
    method: "post",
    baseURL: `http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.username}`,
    timeout: 2000,
  })
    .then((reg) => {
      xml2js
        .parseStringPromise(reg.data, { mergeAttrs: true })
        .then((result) => {
          if (result.RegisterClientResponse.ResponseCode[0] === "0") {
            const clientId = result.RegisterClientResponse.ClientId[0];
            user.avayaClientId = clientId;
            user.save();
          }
          const clientId = user.avayaClientId;
          axios({
            method: "post",
            url: `http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`,
          }).then((notification) => {
            xml2js
              .parseStringPromise(notification.data, { mergeAttrs: true })
              .then((result) => {
                const notifType = [];
                const notifDetails = [];

                for (let i in result.NextNotificationResponse) {
                  notifType.push(i);
                }

                const arranged = {
                  NotificationType: notifType[1],
                  ResponseCode:
                    result.NextNotificationResponse[notifType[0]][0],
                };

                for (let i in result.NextNotificationResponse[
                  notifType[1]
                ][0]) {
                  notifDetails.push(i);
                }

                for (let i = 0; i < notifDetails.length; i++) {
                  arranged[[notifDetails[i]][0]] =
                    result.NextNotificationResponse[notifType[1]][0][
                      notifDetails[i]
                    ][0];
                }

                for (let i in arranged) {
                  if ("Outbound" in arranged) {
                    arranged.CallType = "Outbound";
                  } else if ("Inbound" in arranged)
                    arranged.CallType = "Inbound";
                  else {
                    arranged.CallType = " ";
                  }
                }

                if (
                  arranged.NotificationType === "VoiceInteractionCreated" ||
                  arranged.NotificationType === "VoiceInteractionMissed" ||
                  arranged.NotificationType === "VoiceInteractionTerminated"
                ) {
                  const newLogs = new Avaya({
                    notification: arranged,
                  });

                  newLogs.owner = user;

                  newLogs.save();

                  user.avayaNotifications.push(newLogs),
                    user
                      .save()
                      .then((logs) => res.json(logs))
                      .catch((err) => res.status(400).json("Error: " + err));
                } else {
                  res.send("Nothing to record");
                }
              });
          });
        });
    })
    .catch((err) => res.status(503).json(err));
});

router.route("/history/:username").get(async (req, res) => {
  const user = await User.findOne({ username: [`${req.params.username}`] });
  Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});

module.exports = router;
 

РЕДАКТИРОВАТЬ: я смог исправить благодаря @Molda, использование fetch вместо ax ios не приводит к ошибке cors. Новый код внешнего интерфейса

  getLogs = async () => {
    const { user } = this.props.auth;
    const reg = await fetch(
      `http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.id}`
    );

    let regData = await reg.text();
    let regxml = new XMLParser().parseFromString(regData);

    if (regxml.attributes.ResponseCode === "0") {
      axios.post(`/api/avaya/register/${user.id}`, regxml);
      console.log(regxml.attributes.ResponseCode);
    }

    let resp = await fetch(`/api/avaya/getid/${user.id}`);
    let clientId = await resp.text();

    let logs = await fetch(
      `http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`
    );

    let data = await logs.text();
    var xml = new XMLParser().parseFromString(data);
    axios.post(`/api/avaya/getlogs/${user.id}`, xml);
  };

  timer = (time) => {
    const date = new Date(time);
    return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
  };

  componentDidMount() {
    this.getLogs();
    this.interval = setInterval(this.getLogs, 5000);
  }

Новый код внутреннего интерфейса:

const router = require("express").Router();
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");

router.route("/register/:id").post(async (req, res) => {
  const user = await User.findById(req.params.id);
  const clientId = req.body.attributes.ClientId;
  user.avayaClientId = clientId;
  user.save();
});

router.route("/getid/:id").get(async (req, res) => {
  const user = await User.findById(req.params.id);
  res.send(user.avayaClientId);
});

router.route("/getlogs/:id").post(async (req, res) => {
  const user = await User.findById(req.params.id);

  const arranged = {
    NotificationType: req.body.children[0].name,
    ResponseCode: req.body.attributes.ResponseCode,
    CallType: " ",
  };

  for (let i in req.body.children[0].attributes) {
    if (i === "Outbound") {
      arranged.CallType = "Outbound";
    }
    if (i === "Inbound") {
      arranged.CallType = "Inbound";
    }
    arranged[i] = req.body.children[0].attributes[i];
  }

  console.log(arranged);

  if (
    arranged.NotificationType === "VoiceInteractionCreated" ||
    arranged.NotificationType === "VoiceInteractionMissed" ||
    arranged.NotificationType === "VoiceInteractionTerminated"
  ) {
    const newLogs = new Avaya({
      notification: arranged,
    });

    newLogs.owner = user;

    newLogs.save();

    user.avayaNotifications.push(newLogs),
      user
        .save()
        .then((logs) => res.json(logs))
        .catch((err) => res.status(400).json("Error: " + err));
  } else {
    res.send("Nothing to record");
  }
});

router.route("/history/:username").get(async (req, res) => {
  const user = await User.findOne({ username: [`${req.params.username}`] });
  Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});

module.exports = router;

1 Ответ

0 голосов
/ 20 июня 2020

Я действительно не получаю часть (запрос с помощью Ax ios в API) Это сторонний API?

Но я предлагаю вам использовать (.env), который представляет собой файл в вашей папке root, содержащий конфигурацию разработки, такую ​​как базовые URL-адреса, токены с истекшим сроком действия, ключи API ... et c и при загрузке в Heroku вы должны создать (.env) в приложении Heroku, но ваша конфигурация Давайте возьмем пример

в моем режиме разработки, мой .env выглядит как

app_url = localhost:4000
port = 4000
db = development_api
db_username = root
db_password = 
db_engine = mysql2

в моем производственном режиме, мой .env выглядит как

app_url = http://appsomething.heroku.com
port = 80
db = production_api
db_username = root
db_password = 3210LDWAK@AALKQ
db_engine = mysql2

и прочтите подробнее о том, как использовать .ENV

...