Melayani file statis dengan Sinatra


139

Saya memiliki satu halaman situs web hanya menggunakan HTML, CSS dan JavaScript. Saya ingin menyebarkan aplikasi ke Heroku, tetapi saya tidak dapat menemukan cara untuk melakukannya. Saya sekarang mencoba membuat aplikasi bekerja dengan Sinatra.

.
|-- application.css
|-- application.js
|-- index.html
|-- jquery.js
`-- myapp.rb

Dan berikut ini adalah isi dari myapp.rb.

require 'rubygems'
require 'sinatra'

get "/" do
  # What should I write here to point to the `index.html`
end

1
Saya telah belajar bahwa mengakses localhost: 2345 / index.html berfungsi.
TK.

Anda dapat menggunakan WebBrick untuk menyajikan file statis dalam beberapa baris. require 'webrick'; server = WEBrick::HTTPServer.new Port: 1234; server.mount '/', WEBrick::HTTPServlet::FileHandler, 'www/'; trap("INT") { server.stop }; server.start;Kemudian jalankan ruby myapp.rb. Hapus port untuk Heroku. Masukan web: ruby myapp.rbdalam Anda Procfile. Komentar tidak menjawab karena bukan untuk Sinatra, tapi saya pikir ini menyederhanakan ketergantungan.
Chloe

Jawaban:


131

Tanpa konfigurasi tambahan, Sinatra akan melayani aset di public. Untuk rute kosong, Anda harus merender dokumen indeks.

require 'rubygems'
require 'sinatra'

get '/' do
  File.read(File.join('public', 'index.html'))
end

Rute harus mengembalikan Stringyang menjadi badan respons HTTP. File.readmembuka file, membaca file, menutup file dan mengembalikan a String.


52
Anda sebaiknya melakukannya send_file File.expand_path('index.html', settings.public).
Konstantin Haase

32
Ini sekarang salah. Anda harus mengganti settings.publicdengan settings.public_folderuntuk mendapatkansend_file File.expand_path('index.html', settings.public_folder)
Alistair Holt

2
@zhirzh send_file, itu melakukan hal-hal tambahan untuk Anda github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L351
iain

1
File.readmembaca seluruh file ke dalam memori. Ini bisa OK atau tidak, tergantung pada ukuran file dan jumlah permintaan bersamaan.
Wayne Conrad

@WayneConrad sebaliknya, send_file tidak apa-apa? atau itu bertindak sama?
Ben

169

Anda dapat menggunakan send_filehelper untuk melayani file.

require 'sinatra'

get '/' do
  send_file File.join(settings.public_folder, 'index.html')
end

Ini akan berfungsi index.htmldari direktori apa pun yang telah dikonfigurasi memiliki file statis aplikasi Anda.


19
Saya pikir aplikasi Sinatra yang lebih baru digunakan set :public_folder, jadi Anda akan menggunakan settings.public_foldersebagai gantinyasettings.public
Andrew

4
Saya memperbarui jawaban untuk menggunakan settings.public_folder. Aplikasi yang lebih lama mungkin masih perlu menggunakan settings.public.
Chad DeShon

62

Anda bisa menghosting mereka dari folder publik dan mereka tidak perlu rute.

.
-- myapp.rb
`-- public
    |-- application.css
    |-- application.js
    |-- index.html
    `-- jquery.js

Di myapp.rb

set :public_folder, 'public'

get "/" do
  redirect '/index.html'
end

Tautan ke beberapa sub folder di depan umum

set :public_folder, 'public'
get "/" do
  redirect '/subfolder/index.html' 
end

Semua yang ada di ./publik dapat diakses dari '/apa pun/bla.html

Contoh:
./public/stylesheets/screen.css
Akan dapat diakses melalui '/stylesheets/screen.css' tidak perlu rute


1
bagaimana jika publik memiliki banyak folder bersarang (yang Anda tidak ingin membuat rute) yang memiliki file index.html Anda ingin menjadi default?
Derek Sebelum

Saya telah memperluas solusinya. Saya harap ini membantu memperjelas, semuanya dapat diakses di depan umum, tidak ada rute yang diperlukan hanya menghilangkan bagian 'publik' dari jalur.
Morgan

1
menggunakan rackup di Heroku yang harus saya gunakan set :public_folder, 'public'. Itu adalah kunci untuk membuatnya berfungsi, meskipun dokumentasi Sinatra menyiratkan bahwa ini sudah ditetapkan sebagai default.
Daniel C

12

Perlu diingat bahwa dalam produksi, server web Anda dapat mengirim index.htmlsecara otomatis sehingga permintaan tidak pernah sampai ke Sinatra. Ini lebih baik untuk kinerja karena Anda tidak harus melalui tumpukan Sinatra / Rack hanya untuk menyajikan teks statis, yang merupakan hal yang luar biasa dilakukan oleh Apache / Nginx.


Oh ya, ya. Saya hanya akan menggunakan Erb kemudian dan menggunakan Varnish untuk mencairkannya.
ma11hew28

2
Bagaimana Anda mengonfigurasi ini dalam produksi? Saya telah mencari dokumentasi tentang referensi silang ini dengan Sinatra dan Rack tetapi tidak dapat menemukannya. Pada dasarnya saya ingin index.html untuk dimuat di folder publik / apa pun yang memiliki satu jika pengguna hanya menempatkan nama folder

12

Sinatra seharusnya membiarkan Anda menyajikan file statis dari direktori publik seperti yang dijelaskan dalam dokumen :

File Statis

File statis dilayani dari direktori ./public. Anda dapat menentukan lokasi yang berbeda dengan mengatur: opsi publik:

Perhatikan bahwa nama direktori publik tidak termasuk dalam URL. File ./public/css/style.css tersedia sebagai example.com/css/style.css.


4
Mengapa ini memiliki 4 suara? Itu tidak menjawab pertanyaan tentang bagaimana menyajikan dokumen default ketika folder diminta.
Derek Sebelum


2

yang sinatra-assetpack permata menawarkan sejumlah fitur. Sintaksnya manis:

serve '/js', from: '/app/javascripts'

sementara saya masih mengalami masalah dengan pipeline aset rel saya merasa seperti saya memiliki kontrol lebih banyak menggunakan sinatra-assetpack - tetapi sebagian besar waktu itu hanya bekerja dengan beberapa baris kode.


2

JAWABAN TERBARU YANG : Saya mengikat semua hal di atas tanpa keberuntungan bisa memuat css, js .... dll. Konten satu-satunya yang memuat adalah index.html ... dan sisanya berjalan = >>404 error

Solusi saya: folder aplikasi terlihat seperti ini.

index.rb == >> Kode Sinatra berjalan.

require 'rubygems'
require 'sinatra'

get '/' do
  html :index
end

def html(view)
  File.read(File.join('public', "#{view.to_s}.html"))
end

public folder== >> berisi yang lainnya ... css, js, blah blah..etc.

user@user-SVE1411EGXB:~/sintra1$ ls
index.rb  public
user@user-SVE1411EGXB:~/sintra1$ find public/
public/
public/index.html
public/about_us.html
public/contact.html
public/fonts
public/fonts/fontawesome-webfont.svg
public/fonts/fontawesome-webfont.ttf
public/img
public/img/drink_ZIDO.jpg
public/js
public/js/bootstrap.min.js
public/js/jquery.min.js
public/js/bootstrap.js
public/carsoul2.html
public/css
public/css/font-awesome-ie7.css
public/css/bootstrap.min.css
public/css/font-awesome.min.css
public/css/bootstrap.css
public/css/font-awesome.css
public/css/style.css
user@user-SVE1411EGXB:~/sintra1$

Sekarang mulai server dan Anda akan dapat menavigasi halaman statis tanpa masalah.

user@user-SVE1411EGXB:~/sintra1$ ruby index.rb 
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on localhost:4567, CTRL+C to stop

2
require 'rubygems'
require 'sinatra'

set :public_folder, File.dirname(__FILE__) + '/../client'
#client - it's folder with all your file, including myapp.rb

get "/" do
  File.read('index.html')
end


1

Anda mungkin mempertimbangkan untuk memindahkan index.htmlfile ke views/index.erb, dan mendefinisikan titik akhir seperti:

get '/' do
  erb :index
end


0

Menempatkan file dalam publicfolder memiliki batasan. Sebenarnya, ketika Anda berada di '/'path root berfungsi dengan benar karena browser akan menetapkan path relatif file css Anda misalnya /css/style.cssdan sinatra akan mencari file di publicdirektori. Namun, jika lokasi Anda misalnya /user/create, maka browser web akan mencari file css Anda/user/create/css/style.css dan akan gagal.

Sebagai solusinya, saya menambahkan pengalihan berikut untuk memuat file css dengan benar:

get %r{.*/css/style.css} do
    redirect('css/style.css')
end

-7

Bagaimana dengan solusi ini? :

get "/subdirectory/:file" do 
  file = params[:file] + "index.html"
  if File.exists?(params[:file])
    return File.open("subdirectory/" + file)
  else
   return "error"
  end
end

jadi jika sekarang Anda menavigasi ke (misalnya) / subdirektori / test / itu akan memuat subdirektori / test / index.html

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.