node.js TypeError: đường dẫn phải tuyệt đối hoặc chỉ định root cho res.sendFile [không thể phân tích cú pháp JSON]


150

[add] Vì vậy, vấn đề tiếp theo của tôi là khi tôi thử thêm một phụ thuộc mới (cài đặt npm --save socket.io). Tệp JSON cũng hợp lệ. Tôi nhận được lỗi này: Không thể phân tích 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 

Vì vậy, tôi đã cố gắng tìm hiểu tại sao lỗi này đã quay trở lại. Tất cả các tệp (HTML, JSON, JS) nằm trong cùng một thư mục trên máy tính để bàn của tôi. Tôi đang sử dụng node.js và socket.io

Đây là tệp JS của tôi:

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

Đây là những gì đang được trả lại:

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)

Câu trả lời:


331

Lỗi khá rõ ràng, bạn cần chỉ định một đường dẫn tuyệt đối (thay vì tương đối) và / hoặc đặt roottrong đối tượng cấu hình cho res.sendFile(). Ví dụ:

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

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

hoặc chỉ định một gốc (được sử dụng làm đường dẫn cơ sở cho đối số đầu tiên để res.sendFile():

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

Chỉ định rootđường dẫn sẽ hữu ích hơn khi bạn chuyển một đường dẫn tệp do người dùng tạo có khả năng chứa các phần không đúng định dạng / độc hại như ..(ví dụ ../../../../../../etc/passwd). Đặt rootđường dẫn ngăn không cho các đường dẫn độc hại đó được sử dụng để truy cập các tệp bên ngoài đường dẫn cơ sở đó.


1
Cách tốt nhất để xác định root là up dir?
SuperUberDuper

1
@SuperUberDuper Ý bạn là như thế path.resolve(__dirname, '.../public')nào? Điều đó sẽ giải quyết thư mục con 'công khai' của thư mục mẹ của tập lệnh.
mscdex

mát mẻ! cái này có lưu trữ vĩnh viễn giá trị này trong __dirname trong tương lai không?
SuperUberDuper

1
Xin chào, tôi đã thử res.sendFile sau (path.resolve (__ dirname + '/index.html', '../')) nhưng nhận được tin nhắn: Không thể NHẬN /
SuperUberDuper

2
@SuperUberDuper <- anh chàng này đã đúng (ít nhất là đối với tôi). Anh ta đang sử dụng chức năng giải quyết bình thường hóa các đường dẫn cho phép bạn điều hướng xung quanh với ../../<etc>cú pháp kiểu. Lưu ý dấu phẩy giữa __dirname../public. Sử dụng dấu + không hoạt động.
Helzgate

20

Hãy thử thêm đường dẫn gốc.

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

12

trong các tệp .mjs hiện tại chúng tôi không có __dirname

vì thế

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

Đây là một giải pháp tốt cho tôi vì yêu cầu của tôi là quay trở lại sau khi nhận được đường dẫn qua __dirname. Vì vậy, tôi đã đưa res.sendFile ('index.html', {root: './public/view'});
nilakantha singh deo

đối với SITEMAP.XML trong handelbars, đây là giải pháp phù hợp. Cảm ơn bạn rất nhiều
Titoih

3

Nếu bạn tin tưởng đường dẫn, path.resolve là một tùy chọn:

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

Lỗi khá đơn giản. Rất có thể lý do là tệp index.html của bạn không nằm trong thư mục gốc.

Hoặc nếu nó nằm trong thư mục gốc thì tham chiếu tương đối không hoạt động.

Vì vậy, bạn cần nói với máy chủ vị trí chính xác của tập tin của bạn. Điều này có thể được thực hiện bằng cách sử dụng phương thức dirname trong NodeJs. Chỉ cần thay thế mã của bạn bằng mã này:

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

Đảm bảo rằng bạn thêm biểu tượng dấu gạch chéo "/" trước trang chủ của bạn. Nếu không, đường dẫn của bạn sẽ trở thành: rootDirectoryindex.html

Trong khi bạn muốn nó là: rootDirectory / index.html


1

Tôi giải quyết điều này bằng cách sử dụng biến đường dẫn. Mã mẫu sẽ trông như dưới đây.

var path = require("path");

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

0

Nếu bạn đang làm việc trên Root Directory thì bạn có thể sử dụng phương pháp này

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

nhưng nếu bạn đang sử dụng các Routes trong một thư mục thì hãy nói rằng /Routes/someRoute.jsbạn sẽ cần phải làm một cái gì đó như thế này

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

0

Trong Bản in có đường dẫn tương đối đến biểu tượng:

import path from 'path';

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

0

Nó sẽ chuyển hướng đến index.html trên cuộc gọi localhost: 8080.

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

0

Tôi đã sử dụng mã bên dưới và cố gắng hiển thị tệp sitemap.xml

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

-1

Điều này có thể được giải quyết theo một cách khác:

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

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

});

process.env.PWD sẽ thêm vào thư mục làm việc khi quá trình được bắt đầu.


-2

Tôi đã làm điều này và bây giờ ứng dụng của tôi đang hoạt động đúng,

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

Đó là thực tế xấu để mã hóa vị trí của tập tin. Nếu bạn triển khai ứng dụng đến một máy khác, đường dẫn của tệp rất có thể sẽ khác
Merve Sahin

-3

Bạn có thể cân nhắc sử dụng dấu gạch chéo kép trên thư mục của mình, vd

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.