jalur absolut res.sendFile

137

Jika saya melakukan

res.sendfile('public/index1.html'); 

maka saya mendapatkan peringatan konsol server

express usang res.sendfile: Gunakan res.sendFilesaja

tetapi bekerja dengan baik di sisi klien.

Tetapi ketika saya mengubahnya ke

res.sendFile('public/index1.html');

Saya mendapatkan kesalahan

TypeError: path harus absolut atau tentukan root res.sendFile

dan index1.htmltidak dirender.

Saya tidak dapat menemukan apa jalan absolut itu. Saya memiliki publicdirektori pada level yang sama dengan server.js. Saya melakukan res.sendFiledari dengan server.js. Saya juga sudah menyatakanapp.use(express.static(path.join(__dirname, 'public')));

Menambahkan struktur direktori saya:

/Users/sj/test/
....app/
........models/
....public/
........index1.html

Apa jalur absolut yang harus ditentukan di sini?

Saya menggunakan Express 4.x.

Kaya Toast
sumber
Jika Anda menggunakan express.staticmiddleware untuk melayani direktori publik Anda, mengapa Anda harus res.sendFilemengirim public/index1.html?
Mike S
1
Saya menelepon res.sendFiledari dalam app.get('/', function(req, res){res.sendFile("...")})untuk mengirimkannya atas permintaan.
Kaya Toast

Jawaban:

311

The express.staticmiddleware terpisah dari res.sendFile, sehingga menginisialisasi dengan path absolut untuk Anda publicdirektori tidak akan melakukan apapun untuk res.sendFile. Anda harus menggunakan jalur absolut secara langsung res.sendFile. Ada dua cara sederhana untuk melakukannya:

  1. res.sendFile(path.join(__dirname, '../public', 'index1.html'));
  2. res.sendFile('index1.html', { root: path.join(__dirname, '../public') });

Catatan: __dirname mengembalikan direktori tempat skrip yang saat ini dijalankan. Dalam kasus Anda, sepertinya server.jsada di app/. Jadi, untuk mendapatkan public, Anda harus kembali keluar satu tingkat pertama: ../public/index1.html.

Catatan: pathadalah modul bawaan yang perlu required agar kode di atas berfungsi:var path = require('path');

Mike S
sumber
14
res.sendFile('../public/index.html', {root: __dirname});juga berfungsi dan lebih pendek
Fabien Sa
Bekerja dengan express dan ide webstorm: tidak ada kesalahan console.log(path.join(__dirname, '../public', 'index.html'));tetapi res.sendFile(path.join(__dirname, '../public', 'index.html'));hanya bekerja dengan var path = require('path');
Quake1TF
Apakah tidak ada cara untuk menetapkan sebelumnya path absolut sehingga dapat digunakan di sendFile?
eran otzap
4
res.sendFile('../public/index.html', {root: __dirname});tidak berfungsi (lagi), karena mengembalikan 403 Forbidden karena pergi di atas root. Lakukan res.sendFile('public/index.html', {root: path.dirname(__dirname)});sebaliknya.
Trevor Robinson
48

Coba saja ini sebagai gantinya:

res.sendFile('public/index1.html' , { root : __dirname});

Ini berhasil untuk saya. root: __ dirname akan mengambil alamat di mana server.js berada dalam contoh di atas dan kemudian untuk menuju ke index1.html (dalam hal ini) jalur yang dikembalikan adalah untuk menuju ke direktori di mana folder publik berada.

Kshitij Choudhary
sumber
Mengapa opsi ini tidak didokumentasikan?
timkay
9
res.sendFile( __dirname + "/public/" + "index1.html" );

di mana __dirnameakan mengelola nama direktori tempat skrip saat ini ( server.js) berada.

SOuřaan Gřg
sumber
Solusi ini sangat mudah. ​​Terima kasih atas bantuannya .. Saya heran mengapa orang merekomendasikan untuk menggunakan paket 'path' untuk melakukan hal yang sama.
The Third
3
@ TheThird kurasa, menggunakan pathmembuatnya os-independent.
kmonsoor
7

Alternatif yang belum terdaftar yang berfungsi untuk saya hanyalah menggunakan path.resolvedengan string terpisah atau hanya satu dengan keseluruhan path:

// comma separated
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src', 'app', 'index.html') );
});

Atau

// just one string with the path
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src/app/index.html') );
});

(Node v6.10.0)

Ide bersumber dari https://stackoverflow.com/a/14594282/6189078

Phil Gibbins
sumber
6

Berdasarkan jawaban lain, ini adalah contoh sederhana tentang bagaimana memenuhi persyaratan yang paling umum:

const app = express()
app.use(express.static('public')) // relative path of client-side code
app.get('*', function(req, res) {
    res.sendFile('index.html', { root: __dirname })
})
app.listen(process.env.PORT)

Ini juga berfungsi sebagai cara sederhana untuk merespons dengan index.html pada setiap permintaan , karena saya menggunakan bintang *untuk menangkap semua file yang tidak ditemukan di direktori statis (publik) Anda; yang merupakan kasus penggunaan paling umum untuk aplikasi web. Ubah ke /untuk mengembalikan indeks hanya di jalur root.

Jaime Gómez
sumber
Bagus. Bagus dan ringkas.
lharby
5

Saya mencoba ini dan itu berhasil.

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

process.cwd() mengembalikan jalur absolut dari proyek Anda.

Kemudian :

res.sendFile( `${process.cwd()}/public/index1.html` );
Abdennour TOUMI
sumber
3

Cara lain untuk melakukan ini dengan menulis lebih sedikit kode.

app.use(express.static('public'));

app.get('/', function(req, res) {
   res.sendFile('index.html');
});
Tim Anishere
sumber
5
Ini menghasilkan "TypeError: path harus absolut atau tentukan root untuk res.sendFile"
GreenAsJade
1

Anda dapat menggunakan send bukannya sendFile sehingga Anda tidak akan menghadapi kesalahan! ini berfungsi akan membantu Anda!

fs.readFile('public/index1.html',(err,data)=>{
if(err){
  consol.log(err);
}else {
res.setHeader('Content-Type', 'application/pdf');

untuk memberi tahu peramban bahwa respons Anda adalah jenis PDF

res.setHeader('Content-Disposition', 'attachment; filename='your_file_name_for_client.pdf');

jika Anda ingin file itu langsung terbuka di halaman yang sama setelah pengguna mengunduhnya, tulis 'inline' sebagai gantinya lampiran dalam kode di atas.

res.send(data)
Apakah
sumber
0

Jika Anda ingin mengatur ini sekali dan menggunakannya di mana-mana, cukup konfigurasikan middleware Anda sendiri. Saat Anda menyiapkan aplikasi Anda, gunakan yang berikut untuk menentukan fungsi baru pada objek respons:

app.use((req, res, next) => {
  res.show = (name) => {
    res.sendFile(`/public/${name}`, {root: __dirname});
  };
  next();
});

Kemudian gunakan sebagai berikut:

app.get('/demo', (req, res) => {
  res.show("index1.html");
});
danp
sumber
0

Saya menggunakan Node.Js dan memiliki masalah yang sama ... Saya memecahkan hanya menambahkan '/' di awal setiap skrip dan tautan ke file statis css.

Sebelum:

<link rel="stylesheet" href="assets/css/bootstrap/bootstrap.min.css">

Setelah:

<link rel="stylesheet" href="/assets/css/bootstrap/bootstrap.min.css">
Jackson D
sumber
Anda harus mengatur server statis ekspres agar bisa berfungsi
Hum4n01d