Obsługa plików statycznych za pomocą Sinatry


139

Mam jedną stronę internetową używającą tylko HTML, CSS i JavaScript. Chcę wdrożyć aplikację w Heroku, ale nie mogę znaleźć sposobu, aby to zrobić. Teraz próbuję, aby aplikacja działała z Sinatrą.

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

A oto treść myapp.rb.

require 'rubygems'
require 'sinatra'

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

1
Dowiedziałem się, że dostęp do localhost: 2345 / index.html działa.
— TK.

Możesz użyć WebBrick do obsługi plików statycznych w kilku wierszach. require 'webrick'; server = WEBrick::HTTPServer.new Port: 1234; server.mount '/', WEBrick::HTTPServlet::FileHandler, 'www/'; trap("INT") { server.stop }; server.start;Następnie biegnij ruby myapp.rb. Usuń port dla Heroku. Włóż web: ruby myapp.rbswój Procfile. Komentarz nie odpowiada, bo to nie jest dla Sinatry, ale myślę, że to upraszcza zależności.
— Chloe

Odpowiedzi:


131

Bez dodatkowej konfiguracji Sinatra będzie obsługiwać zasoby w formacie public. W przypadku pustej trasy będziesz chciał wyrenderować dokument indeksu.

require 'rubygems'
require 'sinatra'

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

Trasy powinny zwracać a, Stringktóre stają się treścią odpowiedzi HTTP. File.readotwiera plik, czyta plik, zamyka plik i zwraca plik String.


52
Powinieneś raczej to zrobić send_file File.expand_path('index.html', settings.public).
— Konstantin Haase,

32
To jest teraz nieprawidłowe. Należy wymienić settings.publicz settings.public_folderdostaćsend_file File.expand_path('index.html', settings.public_folder)
— Alistair Holt

2
@zhirzh send_file, robi dla Ciebie dodatkowe rzeczy github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L351
— m.

1
File.readczyta cały plik do pamięci. Może to być prawidłowe lub nie, w zależności od rozmiaru plików i liczby jednoczesnych żądań.
— Wayne Conrad,

@WayneConrad z drugiej strony, send_file jest w porządku? czy działa tak samo?
— Ben

169

Możesz użyć send_filepomocnika do obsługi plików.

require 'sinatra'

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

Będzie to służyć index.htmlz dowolnego katalogu, który został skonfigurowany jako zawierający pliki statyczne aplikacji.


19
Myślę, że nowsze aplikacje Sinatra używają set :public_folder, więc settings.public_folderzamiast tegosettings.public
— Andrew

4
Zaktualizowałem odpowiedź, aby użyć settings.public_folder. Starsze aplikacje mogą nadal wymagać używania settings.public.
— Chad DeShon

62

Możesz po prostu hostować je z folderu publicznego i nie potrzebują tras.

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

W pliku myapp.rb

set :public_folder, 'public'

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

Link do jakiegoś publicznego podfolderu

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

Wszystko w ./public jest dostępne pod adresem „/cokolwiek/bla.html

Przykład:
./public/stylesheets/screen.css
Będzie dostępny za pośrednictwem „/stylesheets/screen.css”, trasa nie jest wymagana


1
co się stanie, jeśli public ma wiele zagnieżdżonych folderów (dla których nie chcesz tworzyć tras) zawierających pliki index.html, które chcesz, aby były domyślne?
— Derek Prior

Rozszerzyłem rozwiązanie. Mam nadzieję, że pomoże to wyjaśnić, wszystko jest dostępne publicznie, żadna trasa nie jest wymagana, wystarczy pominąć „publiczną” część ścieżki.
— Morgan

1
używając rackup na Heroku, którego musiałem użyć set :public_folder, 'public'. To było kluczem do jego działania, mimo że dokumentacja Sinatry sugerowała, że ​​było to już ustawione jako domyślne.
— Daniel C

12

Pamiętaj, że w środowisku produkcyjnym możesz ustawić index.htmlautomatyczne wysyłanie serwera WWW, aby żądanie nigdy nie dotarło do Sinatry. Jest to lepsze dla wydajności, ponieważ nie musisz przechodzić przez stos Sinatra / Rack tylko po to, aby wyświetlać statyczny tekst, w czym Apache / Nginx są niesamowici.


O tak, duh. Po prostu użyję Erba i lakieru, żeby to spieniężyć.
— ma11hew28,

2
Jak to skonfigurujesz na produkcji? Szukałem dokumentacji na temat tego powiązania z Sinatrą i Rackiem, ale nie mogę jej znaleźć. Zasadniczo chcę, aby plik index.html został załadowany do dowolnego / publicznego folderu, który ma taki folder, jeśli użytkownik umieści tylko nazwę folderu

12

Sinatra powinien pozwolić ci udostępniać pliki statyczne z katalogu publicznego, jak wyjaśniono w dokumentacji :

Pliki statyczne

Pliki statyczne są udostępniane z katalogu ./public. Możesz określić inną lokalizację, ustawiając opcję: public:

Zauważ, że nazwa katalogu publicznego nie jest zawarta w adresie URL. Plik ./public/css/style.css jest udostępniany jako example.com/css/style.css.


4
Dlaczego ma 4 głosy? Nie odpowiada na pytanie, jak przedstawić domyślny dokument, gdy żądany jest folder.
— Derek Prior



2

ZAKTUALIZOWANA ODPOWIEDŹ : Wiązałem wszystko powyższe, ale nie udało mi się załadować zawartości css, js .... itd. Jedyną rzeczą, która się ładowała, jest index.html ... a reszta to = >>404 error

Moje rozwiązanie: folder aplikacji wygląda tak.

index.rb == >> Kod Sinatra idzie.

require 'rubygems'
require 'sinatra'

get '/' do
  html :index
end

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

public folder== >> zawiera wszystko inne ... 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$

Teraz uruchom serwer i będziesz mógł bez problemu poruszać się po statycznych stronach.

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

Możesz rozważyć przeniesienie index.htmlpliku do views/index.erbi zdefiniowanie punktu końcowego, takiego jak:

get '/' do
  erb :index
end


0

Umieszczanie plików w publicfolderze ma pewne ograniczenia. Właściwie, gdy jesteś w katalogu głównym, '/'ścieżka działa poprawnie, ponieważ przeglądarka ustawi względną ścieżkę twojego pliku css na przykład, /css/style.cssa sinatra będzie szukał pliku w publickatalogu. Jeśli jednak Twoja lokalizacja to na przykład /user/create, przeglądarka internetowa będzie szukać pliku css w /user/create/css/style.cssi zawiedzie.

Aby obejść ten problem, dodałem następujące przekierowanie, aby poprawnie załadować plik css:

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

-7

A co z tym rozwiązaniem? :

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

więc jeśli teraz przejdziesz do (na przykład) / subdirectory / test /, załaduje się podkatalog / test / index.html

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.