node.js TypeError:パスは絶対パスであるか、res.sendFileへのルートを指定する必要があります[JSONの解析に失敗しました]


150

[追加]だから私の次の問題は、新しい依存関係を追加しようとするときです(npm install --save socket.io)。JSONファイルも有効です。私はこのエラーを受け取ります:jsonの解析に失敗しました

npm ERR! Unexpected string
npm ERR! File: /Users/John/package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.
npm ERR! 
npm ERR! This is not a bug in npm.
npm ERR! Tell the package author to fix their package.json file. JSON.parse 

だから私はこのエラーが戻ってきた理由を理解しようとしました。すべてのファイル(HTML、JSON、JS)は、デスクトップ上の同じフォルダー内にあります。node.jsとsocket.ioを使用しています

これは私のJSファイルです:

var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.sendFile('index.html');
});

http.listen(3000,function(){
    console.log('listening on : 3000');
});

これは返されているものです:

MacBook-Pro:~ John$ node /Users/John/Desktop/Chatapp/index.js 
listening on : 3000
TypeError: path must be absolute or specify root to res.sendFile
    at ServerResponse.sendFile (/Users/John/node_modules/express/lib/response.js:389:11)
    at /Users/John/Desktop/Chatapp/index.js:5:7
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at next (/Users/John/node_modules/express/lib/router/route.js:100:13)
    at Route.dispatch (/Users/John/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at /Users/John/node_modules/express/lib/router/index.js:234:24
    at Function.proto.process_params (/Users/John/node_modules/express/lib/router/index.js:312:12)
    at /Users/John/node_modules/express/lib/router/index.js:228:12
    at Function.match_layer (/Users/John/node_modules/express/lib/router/index.js:295:3)
TypeError: path must be absolute or specify root to res.sendFile
    at ServerResponse.sendFile (/Users/John/node_modules/express/lib/response.js:389:11)
    at /Users/John/Desktop/Chatapp/index.js:5:7
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at next (/Users/John/node_modules/express/lib/router/route.js:100:13)
    at Route.dispatch (/Users/John/node_modules/express/lib/router/route.js:81:3)
    at Layer.handle [as handle_request] (/Users/John/node_modules/express/lib/router/layer.js:76:5)
    at /Users/John/node_modules/express/lib/router/index.js:234:24
    at Function.proto.process_params (/Users/John/node_modules/express/lib/router/index.js:312:12)
    at /Users/John/node_modules/express/lib/router/index.js:228:12
    at Function.match_layer (/Users/John/node_modules/express/lib/router/index.js:295:3)

回答:


331

エラーはかなり明確です。(相対パスではなく)絶対パスを指定するかroot、の設定オブジェクトに設定する必要がありますres.sendFile()。例:

// assuming index.html is in the same directory as this script

res.sendFile(__dirname + '/index.html');

または、ルートを指定します(これは、最初の引数の基本パスとして使用されますres.sendFile()

res.sendFile('index.html', { root: __dirname });

rootパスの指定は、..(たとえば../../../../../../etc/passwd)のような不正な形式/悪意のある部分を含む可能性のあるユーザー生成のファイルパスを渡す場合により便利です。rootパスを設定すると、そのような悪意のあるパスを使用して、そのベースパスの外部にあるファイルにアクセスすることが防止されます。


1
ルートをディレクトリとして指定する最良の方法は何ですか?
SuperUberDuper 2016年

1
@SuperUberDuperどういう意味path.resolve(__dirname, '.../public')ですか?これは、スクリプトの親ディレクトリの「public」サブディレクトリに解決されます。
mscdex 2016年

涼しい!これは将来的にこの値を__dirnameに永続的に保存しますか?
SuperUberDuper

1
こんにちは、私は次のres.sendFile(path.resolve(__ dirname + '/index.html'、 '../'))を試しましたが、メッセージを取得できません:GETできません/
SuperUberDuper

2
@SuperUberDuper <-この男はそれを正しかった(少なくとも私にとっては)。彼はパスを正規化するresolve関数を使用して、../../<etc>型構文でナビゲートできるようにしています。__dirnameとの間のコンマに注意してください../public。+記号を使用しても機能しません。
Helzgate 2016

20

ルートパスを追加してみてください。

app.get('/', function(req, res) {
    res.sendFile('index.html', { root: __dirname });
});

12

.mjsファイルでは、今のところ__dirnameはありません

したがって

res.sendFile('index.html', { root: '.' })

私の要件は__dirnameを経由してパスを取得した後に戻ることでしたので、これは私にとってうまくいった解決策です。
nilakantha singh deo

ハンドバーのSITEMAP.XMLの場合、これは適切なソリューションです。どうもありがとうございました
titoih

3

パスを信頼できる場合、path.resolveはオプションです。

var path = require('path');

// All other routes should redirect to the index.html
  app.route('/*')
    .get(function(req, res) {
      res.sendFile(path.resolve(app.get('appPath') + '/index.html'));
    });

3

エラーはかなり簡単です。最も可能性の高い理由は、index.htmlファイルがルートディレクトリにないことです。

または、それがルートディレクトリにある場合、相対参照は機能しません。

したがって、ファイルの正確な場所をサーバーに伝える必要があります。これは、NodeJでdirnameメソッドを使用して行うことができます。コードを次のコードに置き換えるだけです。

 app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

必ず、ホームページの前にスラッシュ「/」記号を追加してください。そうでない場合、パスは次のようになります。rootDirectoryindex.html

これを次のようにしたい場合:rootDirectory / index.html


1

パス変数を使用してこれを解決します。サンプルコードは以下のようになります。

var path = require("path");

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname + '/index.html'));
})

0

ルートディレクトリで作業している場合は、このアプローチを使用できます

res.sendFile(__dirname + '/FOLDER_IN_ROOT_DIRECTORY/index.html');

ただし、フォルダ内にあるルートを使用している場合は/Routes/someRoute.js、次のようにする必要があります。

const path = require("path");
...
route.get("/some_route", (req, res) => {
   res.sendFile(path.resolve('FOLDER_IN_ROOT_DIRECTORY/index.html')
});

0

アイコンへの相対パスを持つTypescriptで:

import path from 'path';

route.get('/favicon.ico', (_req, res) => res.sendFile(path.join(__dirname, '../static/myicon.png')));

0

localhost:8080呼び出しでindex.htmlにリダイレクトします。

app.get('/',function(req,res){
    res.sendFile('index.html', { root: __dirname });
});

0

以下のコードを使用して、sitemap.xmlファイルを表示しようとしました

router.get('/sitemap.xml', function (req, res) {
    res.sendFile('sitemap.xml', { root: '.' });
});

-1

これは別の方法で解決できます:

app.get("/", function(req, res){

    res.send(`${process.env.PWD}/index.html`)

});

process.env.PWD プロセスが開始されたときに作業ディレクトリを追加します。


-2

私はこれを行い、今私のアプリは適切に動作しています、

res.sendFile('your drive://your_subfolders//file.html');

ファイルの場所をハードコードすることは悪い習慣です。アプリケーションを別のマシンにデプロイした場合、ファイルのパスはおそらく異なります
Merve Sahin

-3

ディレクトリでダブルスラッシュを使用することを検討するかもしれません。例:

app.get('/',(req,res)=>{
    res.sendFile('C:\\Users\\DOREEN\\Desktop\\Fitness Finder' + '/index.html')
})

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.