API 通过 Docker 和 Nodejs 请求失败,但在使用 Nodejs 直接访问时工作正常

API request through Docker & Nodejs fails but works perfectly when accessed directly using the Nodejs

我正在使用 Nodejs and Docker 开发应用程序。在代码中,我需要向 GitLab API 发出请求以获取数据。当我通过 Docker 命令 运行 应用程序时 docker-compose exec web sh -c "project=GitLab type=New npm start" 然后我收到错误,因为它无法从 API 调用但相同的代码和 API 请求在 运行 直接命令 node index.js.

时完美运行

以下是我的代码:

./web/index.js:

const   express     =   require('express');
const   http        =   require("http");
const   bodyParser  =   require('body-parser');
const   app         =   express();
const   port        =   process.env.PORT || 9000;
const   gitlabDump  =   require("./controller/GitLabDump");

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

//Make NodeJS to Listen to a particular Port in Localhost
app.listen(port, function(){
    
    var project = process.env.project;
    var type    = process.env.type;

    if(project.trim() === "GitLab" && (type.trim() === "New" || type.trim() === "Update")){
        //If porject is GitLab then fetch the data from Gitlab
        console.log("Fetching GitLab Data.......");

        gitlabDump.gitlabDump(type, function(data){
            console.log("Completed Execution for GitLab")
            process.exit();
        })
    }
}

以下是我发出 API 请求的控制器代码: ./web/controller/GitLabDump.js

const request = require('request');

exports.gitlabDump = function(callback){
    var gitlabAPI = "https://gitlab.com/api/v4/projects/<project_id>/repository/tree?ref=<target_branch>&path=path/to/subdirectory";

    console.log("BEFORE \n")

    request(gitlabAPI, function(error, response, body) {
        console.log(JSON.parse(body)) 
        callback("Completed");
    })
}

以下是我的Docker文件: ./docker.compose.yml

version: '3'

services:
  db:
    container_name: db
    image: mysql:5.7
    volumes:
      - "./data/mysql:/var/lib/mysql:rw"
    environment:
      MYSQL_DATABASE: myDatabase
      MYSQL_ROOT_PASSWORD: myPassword
      MYSQL_PASSWORD: myPassword
      DATABASE_HOST: localhost
    restart: always

  web:
    container_name: web
    image: node:8
    volumes:
      - ./web:/usr/src/app
    working_dir: /usr/src/app
    depends_on:
      - db
    restart: on-failure
    command: "tail -f /dev/null"
    environment: ["project=${project}", "type=${type}"]

以下是我用于 运行 应用程序的命令:

docker-compose exec web sh -c "project=GitLab type=New npm start"

以下是我得到的错误:

Fetching GitLab Data.......
BEFORE 

undefined:1
undefined
^

由于第 console.log(JSON.parse(body)) 行出现错误。因为 body 未定义为 API 调用 returns 没有数据。

请注意:

  1. API URL 是正确的,我有正确的访问权限,因为相同的 URL 在通过 Chrome、Postman 访问时给我数据,甚至当使用 node index.js 命令 运行 宁代码时。

  2. 除了 GitLab 之外,我正在使用相同的应用程序进行其他 API 调用,它们工作正常。

有人能帮我看看这里的问题是什么以及为什么 GitLab API 失败了吗?

将答案张贴在这里,因为它可能对以后的其他人有用:

终于,我找到了解决办法。问题的发生不是因为 docker,而是因为 Nodejs 本身。如果我们 console.log 错误然后我们得到 certificate has expired 消息。

解决方法是 request 像这样:

request({
  url: gitlabAPI,
  agentOptions: {
    rejectUnauthorized: false
  }
}, function (error, response, body) {
  console.log(JSON.parse(response.body))
});

参考题目:Node.js request CERT_HAS_EXPIRED