繁体   English   中英

部署到 Heroku 时如何使 api 端点目标用户的本地主机

[英]How to make api endpoint target user's localhost when deployed to Heroku

我有这个 api 在本地运行时工作正常。 但是,一旦它被部署到 Heroku 我得到一个错误 503 这是因为它试图在 Heroku 的服务器上定位本地主机而不是用户的本地主机。 有没有办法让这个目标成为用户的本地主机?

前端是 React。 这是 React 中的代码,它每 5 秒获取一次 api。

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 而不是 axios 不会导致 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;

我真的不明白(在 API 中使用 Axios 请求)
这是第三方 API 吗?

但我建议您使用 (.env),它是您根文件夹中的一个文件,其中包含开发配置,如基本 URL、过期令牌、API 密钥……等等,当您上传到 Heroku 时,您必须制作一个 (.env)在 Heroku 应用程序中,但您的配置
举个例子

在我的开发模式下, my.env 看起来像

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

在我的生产模式下, my.env 看起来像

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

并阅读有关如何使用.ENV的更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM