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

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

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

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

Q&A

解決済

1回答

1808閲覧

Content-type': 'application/jsonが反映されません(Node.js)。

keite

総合スコア11

Node.js

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

0グッド

0クリップ

投稿2019/07/10 15:42

前提・実現したいこと

jsonファイルを読み込む。

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

Chromeで127.0.0.1:8000/apiにアクセスしてもjsonファイルを読み込みません。またデベロッパーツールで確認したところ、res.writeHead部分が反映されず、content-typeが設定できていないようです。res.writeHead(200, {'Content-type': 'application/json'}と指定しているのですが。
別の箇所で'Content-type' : 'text/html'と指定しているところ(404)はデベロッパーツールで確認すると、ちゃんと反映されています。
コードにどこか間違いがありますでしょうか。よろしくお願いいたします。

デベロッパーツールの画面

該当のソースコード

node.js

1 2const fs = require('fs'); 3const http = require('http'); 4const url = require('url'); 5 6 const server = http.createServer((req, res) => { 7 8 const pathName = req.url; 9 10 if(pathName === '/'){ 11 res.end('This is top page'); 12 }else if(pathName === '/api'){ 13 14 fs.readFile(`${__dirname}/data/data.json`, 'utf-8', (err, data)=>{ 15 const myData = JSON.parse(data); 16 res.writeHead(200, {'Content-type': 'application/json'}); 17 console.log(myData); 18 res.end(data); 19 }); 20 }else{ 21 res.writeHead(404, { 22 'Content-type' : 'text/html' 23 }); 24 res.end('<h1>Page not found</h1>'); 25 } 26 res.end('Hello!'); 27 }); 28 29 server.listen(8000, '127.0.0.1', () =>{ 30 console.log('Listening'); 31 });

試したこと

console.log(myData)はきちんと動いています。
Chrome、 Firefox, Safariで表示させてもだめでした。
プライベートモードやキャッシュの削除をしても変わりませんでした。

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

Node.js v10.16.0
mac OS Mojave
Google Chrome

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

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

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

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

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

guest

回答1

0

ベストアンサー

この問題の原因はjsの非同期的な動きによるものだと思います。
参考サイト
参考サイト

細かい説明は参考サイトに投げます。

ざっくり説明すると、Node.jsは処理に時間が掛かる動作や関数を後回しにして、他の処理を先に行う性質があります。
つまり、通常であれば上から下へ順番に処理されますが、ときどき順番を無視した処理が行われるのです。

今回の場合ですと、fs.readFile関数が処理に時間がかかる関数です。
この関数内の処理を待っている間に、先に処理を進めてif分の終わりまで行きます。そしてres.end('Hello!');を先に実行してしまうのです。
後からres.end(data);が実行されますが、すでにクライアントへres.end('Hello!');でデータを渡しているため、jsonファイルは表示されません。
これが問題の原因です。

これの解決のためには非同期処理を行えばいいのですが、難解なのでfs.readFileSync関数を使うことをおすすめします。
こちらを使えば、通常の上から下へ順番に処理されます。
fs.readFileSync参考サイト

}else if(pathName === '/api'){ const data = fs.readFileSync(`${__dirname}/data/data.jsone`, 'utf-8') res.writeHead(200, {'Content-type': 'application/json'}); res.end(data); }else{

参考になれば幸いです。

投稿2019/07/10 17:57

編集2019/07/12 03:55
ttakatech

総合スコア118

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

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

keite

2019/07/10 19:16

丁寧な説明をしていただき、ありがとうございます。 しかしながら、試してみましたが、readFileSyncにしても、jsonファイルは読み込めないままです。
ttakatech

2019/07/11 06:12 編集

私の環境では動作しているので、ファイルパスに原因があるのかな?っと思います。 `${__dirname}/data/data.json`←この部分です。 これをconsole.logで確認して頂けないでしょうか。 また、一応確認したいのですが、目的はjsonファイルをブラウザで表示するということでよろしいでしょうか。
keite

2019/07/11 09:52

練習目的で、ブラウザでjsonファイルが表示させることであっています。 127.0.0.1:8000/apiにアクセスしてみると、console.log(myData)では以下のように表示されます。 ``` [ { id: 0, Name: 'Taro', from: 'Tokyo', sex: 'male', description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non felis feugiat, cursus mi non, vehicula felis. Duis dignissim ipsum ac lorem pulvinar, sit amet gravida augue posuere. ' }, { id: 1, Name: 'Hanako', from: 'Osaka', sex: 'female', description: ' In nec arcu vitae ipsum blandit interdum. Donec pellentesque ex leo, nec commodo libero tincidunt id. Proin fringilla laoreet tellus, tempus elementum dolor euismod quis. ' } ] ``` `const data = fs.readFileSync(`${__dirname}/data/data.json`, 'utf-8');`を一番上に持っていく(グローバル変数?)と、ブラウザで表示されました。
ttakatech

2019/07/11 10:04

では、res.end('Hello!');を削除してみてください。
keite

2019/07/11 14:14

すみません、readFileSyncに書き換える際に打ち間違いがあったようです。 res.endを削除しなくても、jsonファイルが表示されました。 お付き合いいただきありがとうございました。
ttakatech

2019/07/11 15:03

解決されたようで何よりです。 かんばってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問