【问题标题】:REST urls returning error or failed to connectREST url 返回错误或连接失败
【发布时间】:2020-04-24 11:20:14
【问题描述】:

我正在尝试从 MongoDB Atlas 集群中获取数据。这在 localhost 上运行良好,但是在 google cloud 上尝试时,发送用于获取产品的 URL 失败。

以下是 URL 的格式:

import {DataTypes} from "./Types";

const protocol = "https";
// const hostname = "localhost"; <- this here works on localhost
const hostname = "ugo-dapashirts.appspot.com";
const port = process.env.PORT || 9090;

export const RestUrls = {
    [DataTypes.PRODUCTS]: `${protocol}://${hostname}:${port}/products`,
    [DataTypes.CATEGORIES]: `${protocol}://${hostname}:${port}/categories`,
    [DataTypes.ORDERS]: `${protocol}://${hostname}:${port}/orders`
}

这是我的 server.js 文件:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require("cors");
const port = process.env.PORT || 9090

const app = express();

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

// Configuring the database
const dbConfig = require('./config/database.config.js');
const mongoose = require('mongoose');

mongoose.Promise = global.Promise;

// Connecting to the database
mongoose.connect(dbConfig.url, {
    useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true
}).then(() => {
    console.log("Successfully connected to the database");    
}).catch(err => {
    console.log('Could not connect to the database. Exiting now...', err);
    process.exit();
});

// Require routes
require('./routes/department.routes.js')(app);
require('./routes/category.routes.js')(app);
require('./routes/product.routes.js')(app);
require('./routes/order.routes.js')(app);

app.listen(port, () => {
    console.log("Server is listening on port 9090");
});

这是一个示例路由文件:

module.exports = (app) => {
    const products = require('../controllers/product.controllers.js');

    // Create a new product
    app.post('/api/products', products.create);

    // Retrieve all products
    app.get('/api/products', products.findAll);

    // Retrieve a single product with productId
    app.get('/api/products/:productId', products.findOne);

    // Retrieve a products with categoryId
    app.get('/api/products/:categoryId', products.findWithCategoryId);

    // Update a product with productId
    app.put('/api/products/:productId', products.update);

    // Delete a produt with productId
    app.delete('/api/products/:productId', products.delete);
}

还有一个示例控制器文件:

const Product = require('../models/product.model.js');

// Create and Save a new Product
exports.create = (req, res) => {
    // Validate request
    if (!req.body.categoryId) {
        return res.status(400).send({
            error: "categoryId cannot be empty"
        });
    }
    else if (!req.body.name) {
        return res.status(400).send({
            error: "Product name cannot be empty"
        });
    }
    else if (!req.body.description) {
        return res.status(400).send({
            error: "Product description cannot be empty"
        });
    }

    // Create a Product
    const product = new Product({
        category_id: req.body.categoryId,
        name: req.body.name, 
        description: req.body.description,
        price: Number(req.body.price).toFixed(2),
        discounted_price: Number(req.body.discountedPrice).toFixed(2),
        image: req.body.image,
        image_2: req.body.image_2,
        thumbnail: req.body.thumbnail,
        display: Number(req.body.display)
    });

    // Save Product in the database
    product.save()
    .then(data => {
        res.send(data);
    }).catch(err => {
        res.status(500).send({
            error: err.message || "Some error occurred while creating the Product."
        });
    });
};

// Retrieve and return all products from the database.
exports.findAll = (req, res) => {
    Product.find()
    .then(product => {
        res.send(product);
    }).catch(err => {
        res.status(500).send({
            error: err.message || "Some error occurred while retrieving products."
        });
    });
};

// Find a single product with a productId
exports.findOne = (req, res) => {
    Product.findById(req.params.productId)
    .then(product => {
        if(!product) {
            return res.status(404).send({
                error: "Product not found with id " + req.params.productId
            });            
        }
        res.send(product);
    }).catch(err => {
        if(err.kind === 'ObjectId') {
            return res.status(404).send({
                error: "Product not found with id " + req.params.productId
            });                
        }
        return res.status(500).send({
            error: "Error retrieving product with id " + req.params.productId
        });
    });
};

// find product with categoryId
exports.findWithCategoryId =(req, res) => {
    Product.find({category_id: req.params.categoryId})
    .then(product => {
        if(product.length) {
            return res.status(404).send({
                error: "Product not found with categoryId " + req.params.categoryId
            });            
        }
        res.send(product);
    }).catch(err => {
        if(err.kind === 'ObjectId') {
            return res.status(404).send({
                error: "Product not found with categoryId " + req.params.categoryId
            });                
        }
        return res.status(500).send({
            error: "Error retrieving product with categoryId " + req.params.categoryId
        });
    });
};

// Update a product identified by the productId in the request
exports.update = (req, res) => {
    // Validate Request
    if (!req.body.categoryId) {
        return res.status(400).send({
            error: "categoryId cannot be empty"
        });
    }
    else if(!req.body.name) {
        return res.status(400).send({
            error: "Product name cannot be empty"
        });
    }
    else if (!req.body.description) {
        return res.status(400).send({
            error: "Product description cannot be empty"
        });
    }

    // Find Product and update it with the request body
    Product.findByIdAndUpdate(req.params.productId, {
        category_id: req.body.categoryId,
        name: req.body.name, 
        description: req.body.description,
        price: Number(req.body.price).toFixed(2),
        discounted_price: Number(req.body.discountedPrice).toFixed(2),
        image: req.body.image,
        image_2: req.body.image_2,
        thumbnail: req.body.thumbnail,
        display: Number(req.body.display)
    }, {new: true})
    .then(prod => {
        if(!prod) {
            return res.status(404).send({
                error: "Product not found with id " + req.params.productId
            });
        }
        res.send(prod);
    }).catch(err => {
        if(err.kind === 'ObjectId') {
            return res.status(404).send({
                error: "Product not found with id " + req.params.productId
            });                
        }
        return res.status(500).send({
            error: "Error updating product with id " + req.params.productId
        });
    });
};

// Delete a product with the specified productId in the request
exports.delete = (req, res) => {
    Product.findByIdAndRemove(req.params.productId)
    .then(prod => {
        if(!prod) {
            return res.status(404).send({
                error: "Product not found with id " + req.params.productId
            });
        }
        res.send({message: "Product deleted successfully!"});
    }).catch(err => {
        if(err.kind === 'ObjectId' || err.name === 'NotFound') {
            return res.status(404).send({
                error: "Product not found with id " + req.params.productId
            });                
        }
        return res.status(500).send({
            error: "Could not delete product with id " + req.params.productId
        });
    });
};

这是我的 app.yaml

runtime: nodejs10
handlers: 
- url: /api/.*
  script: auto
- url: /(.*\..+)$
  static_files: build/\1
  upload: build/(.*\..+)$
- url: /.*
  static_files: build/index.html
  upload: build/index.html

端口有问题吗?我真的很困惑,GCP 有时很糟糕

【问题讨论】:

  • 如果问题只出现在已部署的环境中,则原因不太可能在您的代码中。您可以包含您的app.yaml 文件吗?此外,您是否在部署时看到来自服务器的任何日志消息(以检查请求是否甚至发送到您的应用程序)?
  • @HenryWoody刚刚添加了app.yaml文件
  • 你检查了服务器的日志吗?
  • 另外,您在生产中将PORT 的值设置为什么?
  • @HenryWoody 服务器的日志并没有真正解释太多。 PORT的值为9090

标签: node.js reactjs mongodb google-app-engine mongoose


【解决方案1】:

根据 Node.js 的 GAE app.yaml 配置中的 documentation,您的服务器必须接受端口 8080 上的请求(您的设置为 9090)。

来自文档(重点是我的):

入口点 |可选的。通过在应用启动时执行 entrypoint 命令覆盖默认启动行为。为了让您的应用接收 HTTP 请求,entrypoint 元素应包含一个命令,该命令启动一个 侦听端口 8080 的 Web 服务器。如果您未指定入口点,App Engine 将使用您的 package.json 文件中指定的启动脚本。

【讨论】:

  • 对不起,我收到错误:GET ugo-dapashirts.appspot.com:8080/products net::ERR_CONNECTION_TIMED_OUT
  • 请求应该转到端口 80,但我相信内部服务器应该在 8080 上运行
  • 您好,我正在取回 HTML 文档而不是 JSON。很累
  • 哦,看起来那将来自您在app.yaml 中的handlers,发送index.html 的人会得到不包含“。”的任何内容。其中的人物。有助于避免前端/后端路由冲突的方法是在您的服务器端路由前加上/api,这样您就可以更改为/api/products,这样,如果您的前端有一个产品页面,您就不会遇到冲突。然后更新handlers 以便index.html 仅发送给不以/api 开头的路由
  • 现在出现内部服务器错误 (500),我已编辑我的问题以包含修改后的 app.yaml
猜你喜欢
  • 2015-01-18
  • 2015-01-05
  • 2014-06-22
  • 2020-11-09
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
相关资源
最近更新 更多