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
TK.
sumber
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.

Tate Johnson
sumber
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.

Ryan Ahearn
sumber
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

Morgan
sumber
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.

Rob Cameron
sumber
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.

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

Tambahkan baris di bawah ini di file rb utama

set :public_folder, 'public'
Muhammad Aamir Talib
sumber
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.

naik opelet
sumber
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
zee
sumber
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
Evan Ross
sumber
1

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

get '/' do
  erb :index
end
bonh
sumber
1

Anda selalu dapat menggunakan Rack :: Static

https://www.rubydoc.info/gems/rack/Rack/Static

Cukup tambahkan baris ini sebelum perintah 'run' ke 'config.ru'

use Rack::Static, :urls => [""], :root => 'public', :index => 'index.html'
terima kasih
sumber
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
Pesona
sumber
-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

sandal jepit
sumber