Обслуговування статичних файлів за допомогою Sinatra


139

У мене одна веб-сторінка, що використовує лише HTML, CSS та JavaScript. Я хочу розгорнути додаток до Heroku, але я не можу знайти спосіб це зробити. Зараз я намагаюся зробити так, щоб програма працювала з Sinatra.

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

А далі - зміст myapp.rb.

require 'rubygems'
require 'sinatra'

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

1
Я дізнався, що доступ до localhost: 2345 / index.html працює.
ТЗ.

Ви можете використовувати WebBrick для подання статичних файлів у декількох рядках. require 'webrick'; server = WEBrick::HTTPServer.new Port: 1234; server.mount '/', WEBrick::HTTPServlet::FileHandler, 'www/'; trap("INT") { server.stop }; server.start;Потім бігайте ruby myapp.rb. Видаліть порт для Heroku. Покладіть web: ruby myapp.rbу своє Procfile. Коментар не відповідає, оскільки це не для Сінатри, але я думаю, що це спрощує залежності.
Хлоя

Відповіді:


131

Без додаткової конфігурації Sinatra обслуговуватиме активи в public. Для порожнього маршруту вам потрібно буде відобразити індексний документ.

require 'rubygems'
require 'sinatra'

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

Маршрути повинні повертати a, Stringякі стають тілом відповіді HTTP. File.readвідкриває файл, читає файл, закриває файл і повертає a String.


52
Ви повинні скоріше зробити send_file File.expand_path('index.html', settings.public).
Костянтин Хаазе

32
Зараз це неправильно. Ви повинні замінити settings.publicз , settings.public_folderщоб отриматиsend_file File.expand_path('index.html', settings.public_folder)
Алістер Холт

2
@zhirzh send_file, це додаткові речі для вас github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L351
iain

1
File.readчитає весь файл в пам'ять. Це може бути добре чи ні, залежно від розміру файлів та кількості одночасних запитів.
Уейн Конрад

@WayneConrad навпаки, send_file у порядку? чи діє так само?
Бен

169

Ви можете використовувати send_fileпомічник для обслуговування файлів.

require 'sinatra'

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

Це буде служити index.htmlз будь-якого каталогу, який був налаштований як статичний файл вашої програми.


19
Думаю, новіші додатки Sinatra використовують set :public_folder, тому ви б settings.public_folderзамість цього використовувалисьsettings.public
Андрій

4
Я оновив відповідь, щоб скористатися налаштуваннями.public_folder. Старіші додатки все ще можуть використовувати налаштування.public.
Чад ДеШон

62

Ви можете просто розмістити їх із загальнодоступної папки, і вони не потребують маршрутів.

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

В myapp.rb

set :public_folder, 'public'

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

Посилання на деяку підпапку в загальнодоступному

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

Все в ./public доступне з '/wwhat/bla.html

Приклад:
./public/stylesheets/screen.css
Буде доступний через '/stylesheets/screen.css' маршрут не потрібен


1
що робити, якщо у загальнодоступних папок є багато вкладених папок (для яких ви не хочете створювати маршрути), у яких є файли index.html, якими ви хотіли б бути за замовчуванням?
Дерек Попередній

Я розширив рішення. Я сподіваюсь, що це допоможе з’ясувати, що все доступне публічно, жоден маршрут не потребує просто опущення «публічної» частини шляху.
Морган

1
використовуючи rackup на Heroku, який мені довелося використовувати set :public_folder, 'public'. Це було ключовим для його роботи, незважаючи на те, що документація про Сінатру передбачає, що це вже встановлено за замовчуванням.
Даніель C

12

Майте на увазі, що на виробництві ваш веб-сервер може надсилатися index.htmlавтоматично, щоб запит ніколи не потрапляв до Сінатри. Це краще для продуктивності, оскільки вам не доведеться проходити через стек Sinatra / Rack просто для подання статичного тексту, що саме Apache / Nginx приголомшує.


О так, так. Я просто використовую Erb тоді і використовую Varnish, щоб перерахувати його.
ma11hew28

2
Як ви це налаштовуєте у виробництві? Я шукав документацію щодо цього перехресного посилання на Sinatra та Rack, але не можу його знайти. В основному я хочу, щоб index.html був завантажений у будь-яку / загальнодоступну папку, у якій є, якщо користувач лише вводить ім'я папки

12

Sinatra повинен дозволяти вам обслуговувати статичні файли з загальнодоступного каталогу, як це пояснено в документах :

Статичні файли

Статичні файли подаються з каталогу ./public. Ви можете вказати інше місце, встановивши параметр: public:

Зауважте, що ім'я загальнодоступного каталогу не включено до URL-адреси. Файл ./public/css/style.css доступний як example.com/css/style.css.


4
Чому за це 4 голоси? Він не відповідає на питання, як представити документ за замовчуванням, коли запитується папка.
Дерек Попередній


2

Сінатра-assetpack камінь пропонує цілу купу можливостей. синтаксис солодкий:

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

в той час як у мене все ще виникають проблеми з трубопроводом активів рейок, я відчуваю, що я маю набагато більше контролю за використанням sinatra-assetpack - але в більшості випадків це працює лише з кількома рядками коду.


2

ОНОВЛЕННЯ ВІДПОВІДЬ : Я зв'язав все вищезазначене, не пощастивши, що я не маю змоги завантажити css, js .... тощо. Вміст, єдине, що завантажувалося, це index.html ... а решта збирається = >>404 error

Моє рішення: папка додатків виглядає приблизно так.

index.rb == >> Синатра код іде.

require 'rubygems'
require 'sinatra'

get '/' do
  html :index
end

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

public folder== >> містить усе інше ... css, js, bla 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$

Тепер запустіть сервер, і ви зможете без проблем переходити через статичні сторінки.

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

Ви можете розглянути можливість переміщення index.htmlфайлу до views/index.erbта визначення кінцевої точки, наприклад:

get '/' do
  erb :index
end


0

Вміщення файлів у publicпапку має обмеження. Насправді, коли ви знаходитесь в кореневому '/'шляху, це працює правильно, оскільки браузер встановить відносний шлях вашого файлу css, наприклад, /css/style.cssа sinatra шукатиме файл у publicкаталозі. Однак, якщо ваше місцеположення є, наприклад /user/create, веб-браузер шукатиме ваш файл css /user/create/css/style.cssі не вдасться.

Як вирішення, я додав таке перенаправлення, щоб правильно завантажити файл css:

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

-7

Що з цим рішенням? :

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

тому якщо ви перейдете до (наприклад) / підкаталога / test /, він завантажить підкаталог / test / index.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.