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)

Answers:


331

错误非常明显,您需要指定一个绝对路径(而不是相对路径)和/或root在config对象中设置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 '16

1
@SuperUberDuper你的意思是喜欢path.resolve(__dirname, '.../public')吗?它将解析为脚本的父目录的“ public”子目录。
mscdex

凉!将来是否将此值永久存储在__dirname中?
SuperUberDuper '16

1
嗨,我尝试了以下res.sendFile(path.resolve(__ dirname +' /
index.html

2
@SuperUberDuper <-这个家伙正确(至少对我来说)。他正在使用resolve函数对路径进行规范化,使您可以使用../../<etc>类型语法进行浏览。注意之间的逗号__dirname../public。使用+号不起作用。
Helzgate

20

尝试添加根路径。

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

12

在.mjs文件中,我们现在没有__dirname

因此

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

这对我来说是一个很好的解决方案,因为我的要求是通过__dirname获得路径后返回。因此,我给出了res.sendFile('index.html',{root:'./public/views'});
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文件不在根目录中。

或者,如果它在根目录中,则相对引用不起作用。

因此,您需要告诉服务器文件的确切位置。这可以通过在NodeJs中使用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,/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 });
});



-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')
})

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.