node.js TypeError: พา ธ ต้องเป็นแบบสัมบูรณ์หรือระบุรูทเพื่อ res.sendFile [ล้มเหลวในการวิเคราะห์ JSON]


152

[เพิ่ม] ดังนั้นปัญหาต่อไปของฉันคือเมื่อฉันลองเพิ่มการพึ่งพาใหม่ (ติดตั้ง npm - บันทึก 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

1
@SuperUberDuper คุณหมายความว่าpath.resolve(__dirname, '.../public')อย่างไร ที่จะแก้ไขในไดเรกทอรีย่อย 'สาธารณะ' ของไดเรกทอรีหลักของสคริปต์
mscdex

เย็น! สิ่งนี้จะเก็บค่านี้ไว้อย่างถาวรในชื่อ __ ในอนาคตหรือไม่
SuperUberDuper

1
สวัสดีฉันลองres.sendFileต่อไปนี้(path.resolve (__ dirname + '/index.html', '../'))แต่ได้รับข้อความ: ไม่สามารถรับ /
SuperUberDuper

2
@ SuperUberDuper <- ผู้ชายคนนี้มันถูกต้อง (อย่างน้อยสำหรับฉัน) เขาใช้ฟังก์ชั่นการแก้ไขที่ทำให้เส้นทางเป็นปกติโดยอนุญาตให้คุณนำทางไปรอบ ๆ ด้วย../../<etc>ประเภทไวยากรณ์ ขอให้สังเกตเครื่องหมายจุลภาคระหว่างและ__dirname ../publicการใช้เครื่องหมาย + ไม่ทำงาน
Helzgate

20

ลองเพิ่มเส้นทางรูท

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

12

ใน. mjs ไฟล์ที่เราไม่มี __ ชื่อ

ด้วยเหตุนี้

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

นี่เป็นวิธีแก้ปัญหาที่ดีสำหรับฉันเนื่องจากความต้องการของฉันคือย้อนกลับไปหลังจากได้รับเส้นทางผ่าน __dirname.So ฉันให้ res.sendFile ('index.html', {root: './public/views'});
nilakantha singh deo

สำหรับ SITEMAP.XML ใน handelbars นี่เป็นทางออกที่ถูกต้อง ขอบคุณมาก
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

หากคุณกำลังทำงานกับไดเรกทอรีรากคุณสามารถใช้วิธีการนี้ได้

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 call

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.