node.js TypeError: шлях повинен бути абсолютним або вказати корінь до res.sendFile [не вдалося проаналізувати JSON]


152

[add] Отже, моя наступна проблема полягає в тому, що коли я намагаюся додати нову залежність (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
який найкращий спосіб вказати корінь як dir?
SuperUberDuper

1
@SuperUberDuper Ви маєте на увазі як path.resolve(__dirname, '.../public')? Це вирішить до загальнодоступного підкаталогу батьківського каталогу скрипту.
mscdex

круто! чи постійно зберігає це значення у __dirname у майбутньому?
SuperUberDuper

1
Привіт, я спробував наступний res.sendFile (path.resolve (__ dirname + '/index.html', '../')), але отримаю повідомлення: Cannot GET /
SuperUberDuper

2
@SuperUberDuper <- цей хлопець мав це правильно (принаймні для мене). Він використовує функцію вирішення, яка нормалізує шляхи, що дозволяють вам орієнтуватися навколо ../../<etc>синтаксису типу. Зауважте кома між __dirnameта ../public. Використання знака + не працює.
Гельцгейт

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 відсутній у кореневій директорії.

Або якщо він знаходиться в кореневому каталозі, то відносне посилання не працює.

Тому вам потрібно повідомити серверу точне розташування вашого файлу. Це можна зробити за допомогою методу dirname у NodeJs. Просто замініть свій код цим:

 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

Якщо ви працюєте над Root Directory, то ви можете використовувати такий підхід

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

Він буде переспрямовано на index.html під час виклику localhost: 8080.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.