Express res.sendfile ném lỗi bị cấm


160

Tôi có mã này:

res.sendfile( '../../temp/index.html' )

Tuy nhiên, nó ném lỗi này:

Error: Forbidden
at SendStream.error (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/send/lib/send.js:145:16)
at SendStream.pipe (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/send/lib/send.js:307:39)
at ServerResponse.res.sendfile (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/response.js:339:8)
at exports.boot (/Users/Oliver/Development/Personal/Reader/server/config/routes.js:18:9)
at callbacks (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:161:37)
at param (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:170:5)
at Object.router (/Users/Oliver/Development/Personal/Reader/node_modules/express/lib/router/index.js:33:10)
at next (/Users/Oliver/Development/Personal/Reader/node_modules/express/node_modules/connect/lib/proto.js:199:15)

Bất cứ ai có thể cho tôi biết tại sao điều này có thể được?


3
Tôi tin rằng đó là vì con đường tương đối; "../" được coi là độc hại. Giải quyết đường dẫn cục bộ trước, sau đó gọires.sendfile
Joe

Làm thế nào để bạn giải quyết các con đường địa phương?

4
path.resolvenên làm những gì bạn cần
Joe

1
Điều đó đã làm nó. Bạn muốn vượt qua điều đó như một câu trả lời?

Câu trả lời:


285

Tôi tin rằng đó là vì con đường tương đối; "../" được coi là độc hại. Giải quyết đường dẫn cục bộ trước, sau đó gọi res.sendfile. Bạn có thể giải quyết đường dẫn với path.resolvetrước.

var path = require('path');
res.sendFile(path.resolve('temp/index.html'));

31
thêm chi tiết sẽ có ích ở đây cho những người mới như tôi
Adam Waite

5
Express coi đường dẫn tương đối sendfilelà xấu. Trừ khi bạn chỉ định roottham số thư mục, như đã thấy ở đây: github.com/visionmedia/express/issues/1465
Joe

2
var path = Yêu cầu ('đường dẫn');
Matt Harrison

1
vâng, bản mã cuối cùng !!
SuperUberDuper

2
Cập nhật @MattHarrison ES6, đối với các gói nhập khẩu, constđược ưu tiên hơnvar
Nino Filiu

39

Câu trả lời này tập hợp các thông tin từ các câu trả lời / nhận xét khác.

Nó phụ thuộc vào việc bạn muốn bao gồm một cái gì đó liên quan đến thư mục làm việc quá trình (cwd) hoặc thư mục tệp. Cả hai đều sử dụng path.resolvechức năng (đặt var path = require('path')ở đầu tệp.

  • liên quan đến cwd: path.resolve('../../some/path/to/file.txt');
  • liên quan đến tập tin: path.resolve(__dirname+'../../some/path/to/file.txt');

Từ việc đọc liên kết từ nhận xét của @ Joe, có vẻ như các đường dẫn tương đối là một rủi ro bảo mật nếu bạn chấp nhận đầu vào của người dùng cho đường dẫn (ví dụ: sendfile('../.ssh/id_rsa')có thể là lần thử đầu tiên của hacker).


1
NHƯ một người mới tôi muốn biết làm thế nào kịch bản hacker đến đây?
bharath muppa

2
Nếu bạn vô tình cho phép người dùng nhập đường dẫn của tệp họ muốn tải xuống, họ có thể tải xuống bất kỳ tệp nào trên hệ thống của bạn (tôi đã đưa ra ví dụ về khóa riêng ssh - sẽ cho họ khả năng giả vờ là PC của bạn ( người đàn ông ở giữa, v.v.)). Có .. hạn chế không cho phép khả năng này vì chỉ có thể truy cập các tệp từ trang web.
derekdreery

30

Các tài liệu hướng dẫn nhanh cho thấy làm việc đó một cách khác nhau, và theo ý kiến của tôi nó làm cho ý nghĩa hơn muộn hơn giải pháp hiện tại.

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

Tùy chọn gốc dường như được đặt ./làm thư mục gốc của dự án của bạn. Vì vậy, tôi không thể nói đầy đủ nơi tệp của bạn có liên quan đến thư mục gốc của dự án, nhưng nếu thư mục tạm thời của bạn ở đó, bạn có thể đặt ./templàm gốc cho tệp bạn đang gửi.


1
Điều này đúng, nhưng nó sử dụng sendFile (viết hoa F, được hỗ trợ bởi Express v4.8.0 trở đi) thay vì sendfile cũ hơn mà OP đang sử dụng. Chỉ cần nói ... =]
RemyNL

À ... bắt tốt. Tôi đã không nhận thấy sự khác biệt nhỏ này. Tôi cũng tự hỏi nếu câu trả lời được chọn hoạt động không phải vì nó sử dụng .sendfilemà bởi vì nó hoàn toàn dựa vào một cái gì đó khác (đường dẫn). Cảm ơn đã chỉ ra điều này.
tenor528

Đơn giản và hiệu quả. Cảm ơn bạn! Điều này làm việc cho tôi hoàn hảo!
Emanuela Colta
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.