Обслуживание статических файлов с помощью Sinatra

140

У меня есть одностраничный веб-сайт, использующий только 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. Комментарий не ответ, так как он не для Sinatra, но я думаю, что он упрощает зависимости.
Хлоя

Ответы:

131

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

require 'rubygems'
require 'sinatra'

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

Маршруты должны возвращать, Stringкоторый становится телом HTTP-ответа. File.readоткрывает файл, читает файл, закрывает файл и возвращает 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
Я обновил ответ, чтобы использовать settings.public_folder. Старым приложениям все равно может потребоваться использовать settings.public.
Chad DeShon
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 доступно из '/whatever/bla.html

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

Морган
источник
1
что, если у public есть много вложенных папок (для которых вы не хотите создавать маршруты), в которых есть файлы index.html, которые вы хотели бы использовать по умолчанию?
Дерек Прайор
Я расширил решение. Надеюсь, это поможет прояснить, все доступно публично, никакой маршрут не требуется, просто опустите «публичную» часть пути.
Морган
1
используя Rackup на Heroku, мне пришлось использовать set :public_folder, 'public'. Это было ключом к его работе, несмотря на то, что документация Sinatra подразумевала, что это уже было установлено по умолчанию.
Daniel C
12

Имейте в виду, что в процессе производства вы можете настроить index.htmlавтоматическую отправку веб-сервера, чтобы запрос никогда не попал в Sinatra. Это лучше для производительности, так как вам не нужно проходить через стек Sinatra / Rack только для обслуживания статического текста, в чем Apache / Nginx отлично справляются.

Роб Кэмерон
источник
Ах да, да. Тогда я просто использую Erb и использую Varnish, чтобы обналичить его.
ma11hew28
2
Как вы это настраиваете в продакшене? Я искал документацию об этой перекрестной ссылке с Sinatra и Rack, но не могу ее найти. По сути, я хочу, чтобы index.html загружался в любую / общедоступную папку, в которой он есть, если пользователь помещает только имя папки
11

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

Статические файлы

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

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

imightbeinatree в Cloudspace
источник
5
Почему за это 4 голоса? Он не отвечает на вопрос, как представить документ по умолчанию при запросе папки.
Дерек Прайор
5

Добавьте строку ниже в основной файл rb

set :public_folder, 'public'
Мухаммад Аамир Талиб
источник
2

Синатра-assetpack камень предлагает целую кучу возможностей. синтаксис приятный:

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

Хотя у меня все еще есть проблемы с конвейером ресурсов rails, я чувствую, что с помощью 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, бла-бла .. и т.д.

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
Эван Росс
источник
2

Вы всегда можете использовать Rack :: Static

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

Просто добавьте эту строку перед командой run в config.ru

use Rack::Static, :urls => [""], :root => 'public', :index => 'index.html'
r0ma
источник
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

тапочки
источник