LoginSignup
0
1

More than 3 years have passed since last update.

ブラウザからNode.js(webサーバ)にアクセスした時のみMongoDBにアクセスできない

Last updated at Posted at 2019-08-16

今、Node.jsをwebサーバとして、クライアントからリクエストがあればファイルを返すことや、DBにアクセスして取得したデータを返すということを行っている。
その一つの処理となっているDBアクセスで躓いている。

できたこと

Node.jsからMongoDBにアクセスかつデータ取得は実現できた。
スクリーンショット 2019-08-16 13.31.40.png

sample.js

sample.js
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');

// Connection URL
const url = 'mongodb://localhost:27017';

// Database Name
const dbName = 'study';

//結果
var value;

const client = new MongoClient(url,{useNewUrlParser: true});

const findDocuments = function(db, callback) {
    // Get the documents collection
    const collection = db.collection('user');
    // Find some documents
    collection.find({}).toArray(function(err, docs) {
        assert.equal(err, null);
        console.log("Found the following records");
        value=docs
        console.log(value);
        callback(docs);
    });
}

// Use connect method to connect to the server
client.connect(function(err) {
    assert.equal(null, err);
    console.log("Connected correctly to server");

    const db = client.db(dbName);

    findDocuments(db, function() {
        client.close(); 
    });
});


実行結果

hasegawa@hasegawa-W76OC:~/デスクトップ/akiyama/Node.js$ sudo node sample.js
[sudo] hasegawa のパスワード: 
[ { _id: 5d5364026ed8a1d78076d1f4,
    dist:
     [ 456,
       442,
       //省略
       461,
       461,
       ... 1900 more items ],
    rot:
     [ 0.05797865190578781,
       0.14626504446713978,
       //省略
       19.726678416929172,
       ... 1900 more items ] } ]

やりたいこと

実際やりたいことは
1. クライアントからサーバにhtmlファイルをリクエスト
2. サーバはhtmlファイルを返す
3. そのhtmlファイルに仕込まれたコードでサーバに再びリクエスト
4. サーバはMongoDBにアクセスし、データを取得して返す

しかし、「できたこと」で使ったコードをそのまま使ってもMongoDBにアクセスできない。
スクリーンショット 2019-08-16 13.41.11.png

webserver.js

webserver.js
// 必要なファイルを読み込み
var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer();

// http.createServerがrequestされたら、(イベントハンドラ)
server.on('request', function (req, res) {
    // Responseオブジェクトを作成し、その中に必要な処理を書いていき、条件によって対応させる
    var Response = {
        "renderHTML": function () {
            var template = fs.readFile('./template/index.html', 'utf-8', function (err, data) {
                // HTTPレスポンスヘッダを出力する
                res.writeHead(200, {
                    'content-Type': 'text/html'
                });

                // HTTPレスポンスボディを出力する
                res.write(data);
                res.end();

            });

        },
        "getThree": function () {
            var template = fs.readFile('./js/three.js-master/build/three.min.js', 'utf-8', function (err, data) {
                // HTTPレスポンスヘッダを出力する
                res.writeHead(200, {
                    'content-Type': 'text/javascript'
                });

                // HTTPレスポンスボディを出力する
                res.write(data);
                res.end();
            });
         },
         "getOrbit": function () {
            var template = fs.readFile('./js/OrbitControls.js', 'utf-8', function (err, data) {
                 // HTTPレスポンスヘッダを出力する
                 res.writeHead(200, {
                     'content-Type': 'text/javascript'
                 });

                 // HTTPレスポンスボディを出力する
                 res.write(data);
                 res.end();
             });
          },
          "getValue": function () {
            const MongoClient = require('mongodb').MongoClient;
            const url = 'mongodb://localhost:27017';

            // Database Name
            const dbName = 'study';

            //結果
            var value;

            const client = new MongoClient(url,{useNewUrlParser: true});

            const findDocuments = function(db, callback) {
             // Get the documents collection
             const collection = db.collection('user');
             // Find some documents
             collection.find({}).toArray(function(err, docs) {
              assert.equal(err, null);
              console.log("Found the following records");
              value=docs
              console.log(value);
              callback(docs);
             });
            }

           // Use connect method to connect to the server
           client.connect(function(err) {
            assert.equal(null, err);
            console.log("Connected correctly to server");

            const db = client.db(dbName);

            findDocuments(db, function() {
             client.close(); 
            });
          });  

            // HTTPレスポンスヘッダを出力する
            res.writeHead(200, {
                'content-Type': 'text/html',
                'Access-Control-Allow-Origin': '*'
            });

            console.log("レスポンス");
            //console.log(result);

            // HTTPレスポンスボディを出力する
            res.write(value);
            res.end();
           }
  };
    // urlのpathをuriに代入
    var uri = url.parse(req.url).pathname;
    console.log(uri);


    // URIで行う処理を分岐させる
    if (uri === "/") {
        // URLが「http://localhost:8080/」の場合、"renderHTML"の処理を行う
        Response["renderHTML"]();
        return;
    } else if (uri === "/js/three.js-master/build/three.min.js") {
        // URLが「http://localhost:8080/js/three.js-master/build/three.min.js」の場合、"getThree"の処理を行う
        Response["getThree"]();
        return;
    } else if (uri === "/js/OrbitControls.js") {
        // URLが「http://localhost:8080/js/OrbitControls.js」の場合、"getOrbit"の処理を行う
        Response["getOrbit"]();
        return;
    } else if (uri === "/get_value") {
        // URLが「http://localhost:8080/get_value」の場合、"getThree"の処理を行う
        Response["getValue"]();
        return;
    };
  });

  // 指定されたポート(1234)でコネクションの受け入れを開始する
  server.listen(1234);
  console.log('Server running at http://localhost:80/');

index.html

index.html
<html>
<head>
    <script type="text/javascript" src="js/three.js-master/build/three.min.js"></script>
    <script type="text/javascript" src="js/OrbitControls.js"></script>
</head>

<body>
    <div id="WebGL-area"></div>

    <script type="text/javascript">
    function getValue() {
      //promiseを使うことで簡潔に記述できる
      return new Promise((resolve, reject) => { //resolveまたはrejectの結果を返す
        var req = new XMLHttpRequest(); // HTTPでファイルを読み込むためのXMLHttpRrequestオブジェクトを生成、サーバと非同期通信するためのAPI
        req.open("get", "http://***:1234/get_value", false);
        req.setRequestHeader("Access-Control-Allow-Origin", "*");
        //受信が成功した時に呼び出されるイベント
        req.onload = () => {
          //通信が正常に終了したかを確認する
          if (req.readyState === 4 && req.status === 200) {
            resolve(req.responseType);
          } else {
            alert(req.status);
            reject(new Error(req.statusText));
          }
        };
        //受信が失敗した時に呼び出されるイベント
        req.onerror = () => {
          reject(new Error(req.statusText));
        };

        req.send(null); // HTTPリクエストの発行
      });
    }




    async function init() {
        var scene = new THREE.Scene();

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(900, 600);

        document.getElementById("WebGL-area").appendChild(renderer.domElement);




        var camera = new THREE.PerspectiveCamera(45, 1.5, 0.1, 1000);
        camera.position.set(30, 45, 30);
        camera.lookAt(scene.position);

        var controls = new THREE.OrbitControls(camera);
        controls.autoRotate = true; //自動周回


        // 座標軸を表示
        var axes = new THREE.AxisHelper(100);
        scene.add(axes);

        //形状オブジェクトの宣言と生成
        var geometry= new THREE.Geometry();

        var value;
        var dis=[];
        var rot=[];
        //dis,rot = await getCSV();
        value = await getValue();
        dis=value.dist;
        rot=value.rot;
        //dis=value.slice(0,2000);
        //rot=value.slice(2001,4000);
        //alert(dis[0]);
        //alert(rot[0]);
        //alert(dis);
        //alert(rot);


        // for(var i=0;i<1000;i++){
        //   geometry.vertices[i]= new THREE.Vector3((data[i][0] * Math.cos( data[i][1] * (Math.PI / 180) ))/2,
        //                                             0,
        //                                             (data[i][0] * Math.sin( data[i][1] * (Math.PI / 180) ))/2);
        // }

        for(var i=0;i<2000;i++){
          var x=(dis[i] * Math.cos( rot[i] * (Math.PI / 180) ))/2;
          var y=(dis[i] * Math.sin( rot[i] * (Math.PI / 180) ))/2;
          //alert(x);
          //alert(y);
          geometry.vertices[i]= new THREE.Vector3(x,0,y);
        }

        //材質オブジェクトの宣言と生成
        var material=new THREE.ParticleBasicMaterial({color: 0xFF0000, size: 10.0});
        //点オブジェクトの生成
        var particles = new THREE.ParticleSystem(geometry,material);
        //点オブジェクトのシーンへの追加
        scene.add(particles);



        render();

        function render() {
            controls.update();
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        }
    }
      window.onload = init
    </script>
</body>
</html>

実行結果

hasegawa@hasegawa-W76OC:~/デスクトップ/akiyama/Node.js$ sudo node webServer.js
[sudo] hasegawa のパスワード: 
Server running at http://localhost:80/
/
/js/three.js-master/build/three.min.js
/js/OrbitControls.js
/get_value
レスポンス
_http_outgoing.js:595
    throw new ERR_INVALID_ARG_TYPE('first argument',
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer. Received type undefined
    at write_ (_http_outgoing.js:595:11)
    at ServerResponse.write (_http_outgoing.js:567:10)
    at Object.getValue (/home/hasegawa/デスクトップ/akiyama/Node.js/webServer.js:91:17)
    at Server.<anonymous> (/home/hasegawa/デスクトップ/akiyama/Node.js/webServer.js:115:29)
    at Server.emit (events.js:198:13)
    at parserOnIncoming (_http_server.js:677:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)

実行結果をみるとclient.connectに入ることができていないことがわかります。

確認したこと

サーバとDBだけのやりとりだとできているので、おそらくネットワーク的な問題。

  • クライアントとサーバ両方のファイアウォールをオフ
hasegawa@hasegawa-W76OC:/etc$ sudo ufw status
状態: 非アクティブ
  • ポート番号 mongodbのポート番号がLISTENになっていることを確認
hasegawa@hasegawa-W76OC:/etc$ netstat -an | grep 27017
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN     
unix  2      [ ACC ]     STREAM     LISTENING     1073161  /tmp/mongodb-27017.sock

127.0.0.1:27017となっているのはこのPCからしかアクセスできないということか。
結局今回はこのPCからアクセスしているから問題ないのか。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1