質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

5830閲覧

Node.jsでの動的webページについて

mutoooooo

総合スコア12

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/10/16 07:20

編集2018/10/16 08:13

前提・実現したいこと

仮想通貨の価格情報を取得して、それをChat.jsでリアルタイム表示しようと思っているのですが、まずnode.jsでwebページを表示しようとした際に、静的なhtmlならば表示できるのですが、chat.jsを使った動的なhtmlを表示することができません(このhtmlwebページを単体で動かそうとすると表示することができます。)何かする必要があるのでしょうか?

発生している問題・エラーメッセージ

Uncaught SyntaxError: Unexpected token < finex.js:1 contentscriptcomm.js:48 CheckAndValidate contentscriptcomm.js:132 prompt ui is not loaded hence fail =127.0.0.1 OnRequest @ contentscriptcomm.js:132 contentscriptcomm.js:48 CheckAndValidate contentscriptcomm.js:132 prompt ui is not loaded hence fail =127.0.0.1 OnRequest @ contentscriptcomm.js:132 contentscriptcomm.js:48 CheckAndValidate contentscriptcomm.js:132 prompt ui is not loaded hence fail =127.0.0.1 OnRequest @ contentscriptcomm.js:132 EventImpl.dispatchToListener @ VM20 extensions::event_bindings:403 publicClassPrototype.(anonymous function) @ VM26 extensions::utils:138 EventImpl.dispatch_ @ VM20 extensions::event_bindings:387 EventImpl.dispatch @ VM20 extensions::event_bindings:409 publicClassPrototype.(anonymous function) @ VM26 extensions::utils:138 messageListener @ VM27 extensions::messaging:240 EventImpl.dispatchToListener @ VM20 extensions::event_bindings:403 publicClassPrototype.(anonymous function) @ VM26 extensions::utils:138 EventImpl.dispatch_ @ VM20 extensions::event_bindings:387 EventImpl.dispatch @ VM20 extensions::event_bindings:409 publicClassPrototype.(anonymous function) @ VM26 extensions::utils:138 dispatchOnMessage @ VM27 extensions::messaging:392

該当のソースコード

javascript

1//サーバー側(test.js) 2 3const http = require('http'); 4 5const hostname = '127.0.0.1'; 6const port = 3001; 7 8var server = http.createServer(); 9server.on('request', doRequest); 10 11// ファイルモジュールを読み込む 12var fs = require('fs'); 13 14// リクエストの処理 15function doRequest(req, res) { 16 17 // ファイルを読み込んだら、コールバック関数を実行する。 18 fs.readFile('./finex.html', 'utf-8' , doReard ); 19 20 21 // コンテンツを表示する。 22 function doReard(err, data) { 23 if (err) { 24 res.writeHead(404, {'Content-Type': 'text/plain'}); 25 res.write("not found!"); 26 return res.end(); 27 } 28 res.writeHead(200, {'Content-Type': 'text/html'}); 29 res.write(data); 30 res.end(); 31 } 32 33} 34 35server.listen(port, hostname, () => { 36 console.log(`Server running at http://${hostname}:${port}/`); 37});

html

1//htmlファイル(finex.html) 2 3 4<head> 5 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script> 6 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.js"></script> 7 <script type="text/javascript" src="https://github.com/nagix/chartjs-plugin-streaming/releases/download/v1.2.0/chartjs-plugin-streaming.js"></script> 8 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pusher/4.1.0/pusher.js"></script> 9 <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script> --> 10</head> 11 12<body> 13 <canvas id="Bitfinex"></canvas> 14 15 <script src="finex.js"></script> 16</body>

javascript

1//finex.htmlで読み込むjs(finex.js) 2 3 4var buf = {}; 5buf['Bitfinex'] = [[],[]] 6 7var ws = new WebSocket('wss://api.bitfinex.com/ws/'); 8ws.onopen = function() { 9 ws.send(JSON.stringify({ // 購読リクエストを送信 10 "event": "subscribe", 11 "channel": "trades", 12 "pair": "BTCUSD" 13 })); 14}; 15ws.onmessage = function(msg) { // メッセージ更新時のコールバック 16 var response = JSON.parse(msg.data); 17 if (response[1] === 'te') { // メッセージタイプ 'te' だけを見る 18 19 buf['Bitfinex'][response[5] > 0 ? 0 : 1].push({ 20 x: response[3] * 1000, // タイムスタンプ(ミリ秒) 21 y: response[4] // 価格(米ドル) 22 }); 23 console.log(buf['Bitfinex']) 24 } 25 26} 27var id = 'Bitfinex'; 28var ctx = document.getElementById(id).getContext('2d'); 29var chart = new Chart(ctx, { 30 type: 'line', 31 data: { 32 datasets: [{ 33 data: buf['Bitfinex'][0], 34 label: 'Buy', // 買い取引データ 35 borderColor: 'rgb(255, 99, 132)', // 線の色 36 backgroundColor: 'rgba(255, 99, 132, 0.5)', // 塗りの色 37 fill: false, // 塗りつぶさない 38 lineTension: 0 // 直線 39 }, { 40 data: [], 41 label: 'Sell', // 売り取引データ 42 borderColor: 'rgb(54, 162, 235)', // 線の色 43 backgroundColor: 'rgba(54, 162, 235, 0.5)', // 塗りの色 44 fill: false, // 塗りつぶさない 45 lineTension: 0 // 直線 46 }] 47 }, 48 options: { 49 title: { 50 text: 'BTC/USD (' + id + ')', // チャートタイトル 51 display: true 52 }, 53 scales: { 54 xAxes: [{ 55 type: 'realtime' // X軸に沿ってスクロール 56 }] 57 }, 58 plugins: { 59 streaming: { 60 duration: 300000, // 300000ミリ秒(5分)のデータを表示 61 refresh: 100, // onRefresh callback will be called every 1000 ms 62 delay: 1000, // delay of 1000 ms, so upcoming values are known before plotting a line 63 pause: false, // chart is not paused 64 onRefresh: function(chart) { // データ更新用コールバック 65 66 Array.prototype.push.apply( 67 chart.data.datasets[0].data, buf[id][0] 68 ); // 買い取引データをチャートに追加 69 Array.prototype.push.apply( 70 chart.data.datasets[1].data, buf[id][1] 71 ); // 売り取引データをチャートに追加 72 buf[id] = [[], []]; // バッファをクリア 73 } 74 } 75 } 76 } 77});

試したこと

htmlファイルではなく、ejsにしなければならないのかなどやって見ては見たのですがよくわかりませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dice142

2018/10/16 07:23

コードやエラー文はコードブロック(```)で囲んでください。
dice142

2018/10/16 07:51

「表示できない」を詳細に書いていただきたいです。どういう風にアクセスしてどういうものが表示されるとか。
mutoooooo

2018/10/16 07:57

本当に真っ白のページから何も変わらず、consoleを見るとこのメッセージのみ見えています。
dice142

2018/10/16 08:03

なるほどです。コードにエラーが有ることが原因かと思いますが、ブラウザで開発者ツールを開くとコンソール欄にエラーが出てると思うので、場合によってはそこも参考にしたほうが良いですね。
guest

回答3

0

ベースはothersightさんの回答。
実際にpathの文字列を見ながらif文を使いつつ手渡すやり方は相当つらいことでしょう。
そこで、普段はExpress.jsを使ってください。

上メニューから解説やガイドを一通り読めば使えるようになるでしょう。

投稿2018/10/16 09:57

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mutoooooo

2018/10/16 13:10

ありがとうございます。もう少しnode.jsについて理解を深めたらExpress.js を利用して見たいと思います。
guest

0

ベストアンサー

サーバ側が、どのようなパスを指定されてもfinex.htmlの内容を返すように実装されているため、このようなエラーが発生しているのではないでしょうか。実際にも、finex.jsの実行結果が、

Uncaught SyntaxError: Unexpected token < finex.js:1

となっていて、これは、ブラウザがfinex.jsと思ってダウンロードできたファイルの中身がfinex.htmlと同じで、最初の文字が「<」となっているために発生した、ということを示しています。

具体的にコード(test.js)を見ていきます。必要な部分だけ抜き出しますと、

js

1server.on('request', doRequest); 2 3function doRequest(req, res) { 4 fs.readFile('./finex.html', 'utf-8' , doReard ); 5 // ^^^^^^^^^^^^ 6 7 function doReard(err, data) { 8 res.writeHead(200, {'Content-Type': 'text/html'}); 9 res.write(data); 10 res.end(); 11 } 12}

と実装されているため、HTTPリクエストの中身にかかわらずfinex.htmlを読み込んでレスポンスボディとして返しています

つまり、リクエストのパスを見て、それに合ったファイル(とContent-Type)を返すようにコードを修正する必要があります。ヒントだけ示しますと、

js

1const url = require('url'); 2 3server.on('request', doRequest); 4 5function doRequest(req, res) { 6 const path = url.parse(req.url).pathname;

のようにしますと、ブラウザから指定されたURL内のファイルパス(/finex.html/finex.jsなど)のような絶対パス)が取得できますので、その値に応じてfs.readFile()で読み込むファイルを切り替えればよい、ということになります。また、res.writeHead()のContent-Typeの値もファイルの種類に応じて変えるようにする必要があります(jsファイルならtext/javascriptなど)。

投稿2018/10/16 09:19

編集2018/10/16 09:22
othersight

総合スコア356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dice142

2018/10/16 09:24

あーーーなるほどそういうことだったんですね。 見当違いな誘導しててすごく恥ずかしい。。。
mutoooooo

2018/10/16 13:08 編集

丁寧な回答ありがとうございます。 自分javascriptやnode.jsに触れるのが今回初めてでまだ理解が不十分なのですが、今回やっているのはサーバーを立ててブラウザがファイルを実行しようとするたびにそのファイル名がrequestとして入ってきて、そのファイルの中身をブラウザに渡してあげるという認識で合っているでしょうか? ``` const http = require('http'); const hostname = '127.0.0.1'; const port = 3002; const url = require('url') var server = http.createServer(); server.on('request', doRequest); // ファイルモジュールを読み込む var fs = require('fs'); // リクエストの処理 function doRequest(req, res) { const path = url.parse(req.url).pathname; console.log(url.parse(req.url)) console.log(path) // ファイルを読み込んだら、コールバック関数を実行する。 if(path=='/'){ fs.readFile('/finex.html', 'utf-8' , doReard ); } else{ fs.readFile(path, 'utf-8' , doReard ); } // コンテンツを表示する。 function doReard(err, data) { if (err) { res.writeHead(404, {'Content-Type': 'text/plain'}); res.write("not found!"); return res.end(); } else if(path=='/finex.html'){ res.writeHead(200, {'Content-Type': 'text/html'}); } else if(path=='/'){ res.writeHead(200, {'Content-Type': 'text/html'}); } else if(path=='/finex.js'){ res.writeHead(200, {'Content-Type': 'text/javascript'}); } else if(path=='/finex.ico'){ res.writeHead(200, {'Content-Type': 'text/ico'}); } res.write(data); res.end(); } } server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); ``` 今回ご指摘を受けて、このようにpathをreadするようにして、if文でcontenttypeを場合分けしようとしたのですが、最初の'/'というpathでつまづき、not found! と表示されてしまいます。 この'/'とはなんなのでしょうか?自分の方向性はこれで合ってますか? よろしくお願いします。
miyabi-sun

2018/10/16 13:29 編集

URLのお勉強が必要そうですね、まずはこちらのURLを見て下さい。 https://ja.wikipedia.org/wiki/Uniform_Resource_Locator URLというのはホスト部(example.com)が終わった後に「/」文字で区切ってパス部が始まります。 このパス部の第1文字目の「/」はルートのパスを表すもので、絶対に必要です。 でも「http://example.com」だけでWebサイトに接続出来るじゃないか!!と思うかも知れませんが、ブラウザが裏でこっそり補っています。 Apache等のWebサーバソフトは「/」で終わるディレクトリと思わしきパスで終わった時、気を利かせて勝手に「/index.html」を探して持ってきてくれる仕様になっています。(この辺は設定ファイルの初期設定に書いてある) ディレクトリで終わるんだから、索引(index)が必要だよねというのりですね。 Node.jsのhttpというモジュールは、 Apacheのようなソフトの力を借りずに自力で立ち上げるわと言ってる訳で、 この辺のよしなにのサポートを全部自分で用意する必要があるので相当辛いです。 ググったりドキュメント読みながらExpress.jsを使えというのはその辺の不便さを解決するために半ば必要なものです。 もしhttpモジュールのまま頑張るのであれば、それなりに苦しみながら少しずつ進めて下さい。 苦しんだ分だけエンジニアとしての力が身につきますからね。
mutoooooo

2018/10/16 14:16

ありがとうございます!URL周り、パスなどの理解が不十分でした。 urlから得たpathの/finex.htmlと、データを読み込む際のデータの場所であるパスの./finex.htmlを混同していました。 上記のコードを以下にしたらうまくwebページを表示することができました。 ```test.js const http = require('http'); const hostname = '127.0.0.1'; const port = 3003; const url = require('url') var server = http.createServer(); server.on('request', doRequest); // ファイルモジュールを読み込む var fs = require('fs'); // リクエストの処理 function doRequest(req, res) { const path = url.parse(req.url).pathname; console.log(url.parse(req.url)) console.log(path) // ファイルを読み込んだら、コールバック関数を実行する。 if(path == '/'){ fs.readFile('./finex.html', 'utf-8' , doReard ); } else{ console.log('.'+path) fs.readFile('.'+path, 'utf-8' , doReard ); } // コンテンツを表示する。 function doReard(err, data) { if (err) { res.writeHead(404, {'Content-Type': 'text/plain'}); res.write("not found!"); return res.end(); } if(path=='/finex.html'){ res.writeHead(200, {'Content-Type': 'text/html'}); } else if(path=='/'){ res.writeHead(200, {'Content-Type': 'text/html'}); } else if(path=='/finex.js'){ res.writeHead(200, {'Content-Type': 'text/javascript'}); } else if(path=='/finex.ico'){ res.writeHead(200, {'Content-Type': 'text/ico'}); } res.write(data); res.end(); } } server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); ``` ただ、いまだに何が起こっているかはよくわからない部分がある上、このような方法は確かに大変だなと感じたので、express.jsを利用していきたいと思います。 丁寧なご指導ありがとうございました。
guest

0

直接的な解決になるかはわかりませんが、気になったところをいくつか。

エラーメッセージを読むと、シンタックスエラーがあるので、
括弧が合ってないとかそういうミスがどこかにありそうです。
contentscriptcomm.jsがなにかはわかりませんが、
そこでもメッセージ出てるので確認したほうが良さそうです。

test.jsの最後のconsole.logの文字列が\``で囲まれています。 '`の間違いじゃないですか?

投稿2018/10/16 07:50

dice142

総合スコア5158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mutoooooo

2018/10/16 08:01

ご指摘ありがとうございます。 このfinex.htmlを例えばhello world とだけ表示するhtmlファイルにすると問題なく表示できるので、シンタックスエラーはないと思うのですが、、 contentsscriptcomn.jsは僕が書いたコードではなく、ライブラリが用いているもので、そのどこかの処理内でエラーが起きていると思うのですが、よくわかりません。
dice142

2018/10/16 08:05

Syntax Errorが出ているので何かしら問題はあるかと思いますが。ファイル名とかの情報は出てませんか? ライブラリを用いているのであればその情報も追記お願いします。
mutoooooo

2018/10/16 08:12

finex.js:1 にシンタックスエラーが出ていました。 すみません、ライブラリというものを勘違いしていたかもしれませんが、このcontentsscriptcomn.jsはnode.jsやchart.js内の処理のコードなのかなと理解していました。
dice142

2018/10/16 08:31

> finex.js:1 にシンタックスエラーが出ていました。 finex.jsが読み込まれていない気がします。ファイル名やパスは合っていますか? > contentsscriptcomn.jsはnode.jsやchart.js内の処理のコードなのかなと理解していました。 IPアドレスが関連してるっぽいので何か通信系のものでしょう。 そちらはtest.jsあたりのものかと思います。
mutoooooo

2018/10/16 08:40

これら3つのファイルは全て同じディレクトリにあるのであっていると思われるのですが、、実際にtest.jsを使わずに、finex.htmlをwebページで開くと、finex.jsを読み込んで表示することができます。これをnode.jsを用いたtest.jsから開けないのは何故なのかが全くわからないです。 やはりtest.jsに問題があるのでしょうか?node.jsからwebページを表示するテンプレのようなものをそのまま用いました。
dice142

2018/10/16 08:42

srcを「./finex.js」にするとどうでしょう?
mutoooooo

2018/10/16 08:50

同じエラーが出てしまいます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問