回答我自己的问题:是的,这是可能的。
就我而言,Rails 并不过分。我与我们基于 Rails 的项目管理系统无缝集成。我正在安装 Sinatra-App 作为 Web 服务器,使用基于用户会话的不同公共 URL。 session 是通过唯一的 token 生成的,这样用户就可以一个接一个地查看不同的静态项目。
routes.rb:
constraints(:subdomain => /preview/) do
mount SinatraWrapper => "/"
end
注意:我在这里使用约束来检查子域。每个静态预览都被重定向到不同子域下的同一个应用程序。
Sinatra 包装器:
# a super-trivial Sinatra-based webserver
# for static content
require 'sinatra/base'
class SinatraWrapper < Sinatra::Base
before '/*' do
SinatraWrapper.set_site(session[:site])
end
def self.set_site(site)
rootPath = File.expand_path("#{Rails.root}/sites/#{site}/")
set :public_folder, "#{rootPath}/current/build/"
end
configure do
set :static, true
set :static_cache_control, [:public, :no_store, :no_cache, :must_revalidate, :max_age => 0, :expires => "Fri, 01 Jan 1990 00:00:00 GMT"]
end
set_site("default")
# route to starting page (index.html)
get "/" do
redirect "/index.html"
end
# route to custom error page (404.html)
not_found do
redirect "/404.html"
end
end
注意:我正在通过 capistrano 将静态项目的更新部署到 rails 应用程序中。构建通过Middleman 远程执行(我们可以在此处使用任何其他静态站点生成器)。另一个实例检查我们的 git 存储库中“预览”分支中的更新并在其上运行测试。通过所有测试后,将自动执行并部署构建。
这里是棘手的一点,对两个不同的子域使用不同的行为,但相同的会话:
# static_pages_controller.rb:
def preview
if request.subdomain == "preview" or Rails.env.development? # local dev: no subdomains
@static_page = StaticPage.find(params[:id])
session[:site] = @static_page.slug || "default" # using a sha-slug for every static project
redirect_to "/" # redirect to root. we have a valid session now.
else
# we are NOT on the preview subdomain, so we need to redirect to proper subdomain
@project = Project.find(params[:project_id])
@static_page = StaticPage.find(params[:id])
redirect_to preview_url(project_id: @project.id, id: @static_page.id, token: @static_page.slug).sub("plattform", "preview")
end
end
注意:我有很多静态页面的项目。我们对平台上的每个静态页面都有一个预览操作。如果您使用来自平台的链接点击预览操作,您将被重定向到预览子域并设置您的会话。我们的身份验证允许我们
- 向客户发送带有身份验证令牌 (SHA-Slug) 的匿名链接
- 并通过数据库进行身份验证
这个系统我们用了半年了,很满意!客户可以立即看到预览。到目前为止,我们还没有遇到任何严重的问题,除了必须正确设置缓存标头以确保每次重新加载页面时都加载新内容。这会减慢体验,但我们总是可以争论,这是一个预览。老实说,大多数客户不知道加载时间。
无论如何,我不能 100% 确定我的“崩溃”缓存的实现是否是完美的解决方案。任何提示将不胜感激。我只在 Chrome 和 Safari 中遇到问题(非常罕见),您需要多次重新加载页面,直到显示新内容。
另一个有趣的问题是安全性。我认为相对安全。但我不是安全专家。有什么顾虑吗?
我们仅在内部使用此平台。没有产品,所以我们不会非常温和地处理错误。