res.sendFile đường dẫn tuyệt đối


137

Nếu tôi làm một

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

sau đó tôi nhận được một cảnh báo giao diện điều khiển máy chủ

express deprecated res.sendfile: Sử dụng res.sendFilethay thế

nhưng nó hoạt động tốt ở phía khách hàng

Nhưng khi tôi đổi nó thành

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

Tôi gặp lỗi

TypeError: đường dẫn phải tuyệt đối hoặc chỉ định root res.sendFile

index1.htmlkhông được kết xuất.

Tôi không thể tìm ra con đường tuyệt đối là gì. Tôi có publicthư mục ở cùng cấp độ với server.js. Tôi đang làm res.sendFiletừ với server.js. Tôi cũng đã tuyên bốapp.use(express.static(path.join(__dirname, 'public')));

Thêm cấu trúc thư mục của tôi:

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

Con đường tuyệt đối được chỉ định ở đây là gì?

Tôi đang sử dụng Express 4.x.


Nếu bạn đang sử dụng express.staticphần mềm trung gian để phục vụ thư mục công cộng của mình, tại sao bạn cần res.sendFilegửi public/index1.html?
Mike S

1
Tôi đang gọi res.sendFiletừ bên trong app.get('/', function(req, res){res.sendFile("...")})để gửi nó theo yêu cầu.
Bánh mì nướng Kaya

Câu trả lời:


310

Phần express.staticmềm trung gian tách biệt với nhau res.sendFile, vì vậy việc khởi tạo nó với một đường dẫn tuyệt đối đến publicthư mục của bạn sẽ không làm gì cả res.sendFile. Bạn cần sử dụng một đường dẫn tuyệt đối trực tiếp với res.sendFile. Có hai cách đơn giản để làm điều đó:

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

Lưu ý: __dirname trả về thư mục mà tập lệnh hiện đang thực thi. Trong trường hợp của bạn, nó trông giống như server.jstrong app/. Vì vậy, để đến được public, bạn cần lùi lại một cấp trước : ../public/index1.html.

Lưu ý: pathlà một mô-đun tích hợp cần phải được required để mã trên hoạt động:var path = require('path');


14
res.sendFile('../public/index.html', {root: __dirname});cũng hoạt động và nó ngắn hơn
Fabien Sa

Làm việc với ide và webstorm ide: không có lỗi trong console.log(path.join(__dirname, '../public', 'index.html'));nhưng res.sendFile(path.join(__dirname, '../public', 'index.html'));chỉ hoạt động với var path = require('path');
Quake1TF

Có cách nào để xác định trước đường dẫn tuyệt đối để nó có thể được sử dụng trong sendFile không?
eran otzap

4
res.sendFile('../public/index.html', {root: __dirname});không hoạt động (nữa), vì nó trả về 403 Bị cấm do đi trên gốc. Làm res.sendFile('public/index.html', {root: path.dirname(__dirname)});thay thế.
Trevor Robinson

48

Chỉ cần thử điều này thay thế:

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

Điều này làm việc cho tôi. thư mục gốc: __ dirname sẽ lấy địa chỉ trong đó server.js trong ví dụ trên và sau đó để đến index1.html (trong trường hợp này), đường dẫn được trả về là đến thư mục chứa thư mục chung.


Tại sao tùy chọn này không được ghi lại?
timkay

9
res.sendFile( __dirname + "/public/" + "index1.html" );

nơi __dirnamesẽ quản lý tên của thư mục mà tập lệnh hiện đang thực thi ( server.js) nằm trong đó.


Giải pháp này khá đơn giản. Cảm ơn sự giúp đỡ .. Tôi tự hỏi tại sao mọi người khuyên bạn nên sử dụng gói 'đường dẫn' để làm điều tương tự.
Thứ ba

3
@TheThird tôi đoán, sử dụng pathlàm cho nó độc lập os.
kmonsoor

7

Một thay thế chưa được liệt kê mà hoạt động với tôi chỉ đơn giản là sử dụng path.resolvevới các chuỗi riêng biệt hoặc chỉ một chuỗi với toàn bộ đường dẫn:

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

Hoặc là

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

(Nút v6.10.0)

Ý tưởng có nguồn gốc từ https://stackoverflow.com/a/14594282/6189078


6

Dựa trên các câu trả lời khác, đây là một ví dụ đơn giản về cách thực hiện yêu cầu phổ biến nhất:

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)

Đây cũng là một cách đơn giản để trả lời với index.html cho mỗi yêu cầu , bởi vì tôi đang sử dụng một ngôi sao *để bắt tất cả các tệp không tìm thấy trong thư mục tĩnh (công khai) của bạn; đó là trường hợp sử dụng phổ biến nhất cho các ứng dụng web. Thay đổi để /trả về chỉ mục trong đường dẫn gốc.


Đẹp. Đẹp và cô đọng.
lharby

5

Tôi đã thử điều này và nó đã làm việc.

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

4

process.cwd() trả về đường dẫn tuyệt đối của dự án của bạn

Sau đó :

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

3

Một cách khác để làm điều này bằng cách viết ít mã hơn.

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

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

5
Điều này tạo ra "TypeError: đường dẫn phải tuyệt đối hoặc chỉ định root cho res.sendFile"
GreenAsJade

1

bạn có thể sử dụng gửi thay vì sendFile để bạn không gặp phải lỗi! công việc này sẽ giúp bạn!

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

để nói với trình duyệt rằng phản hồi của bạn là loại PDF

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

nếu bạn muốn tệp đó mở ngay lập tức trên cùng một trang sau khi người dùng tải xuống. Viết 'nội tuyến' thay vì đính kèm trong mã ở trên.

res.send(data)

0

Nếu bạn muốn thiết lập điều này một lần và sử dụng nó ở mọi nơi, chỉ cần cấu hình phần mềm trung gian của riêng bạn. Khi bạn đang thiết lập ứng dụng của mình, hãy sử dụng cách sau để xác định chức năng mới trên đối tượng phản hồi:

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

Sau đó sử dụng nó như sau:

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

0

Tôi sử dụng Node.Js và có cùng một vấn đề ... Tôi đã giải quyết chỉ cần thêm một '/' trong việc xin mọi tập lệnh và liên kết đến một tệp tĩnh css.

Trước:

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

Sau:

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

Bạn sẽ phải thiết lập máy chủ tĩnh tốc độ để hoạt động này
Hum4n01d
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.