谁定义了要重定向到移动版本的 URL?
让我们以推特为例:
https://twitter.com -> 重定向手机https://dev.twitter.com -> 不重定向手机在 MVC 应用程序中谁负责规则重定向?
www 中的所有内容都可以重定向到移动设备吗?
最佳答案
One way is to use
.htaccessor equivalent tools to redirect from server (apache is not the only webserver) and force a redirect. It's already covered in other answers. But there is a different approach to. One that actually would utilize MVC: do not redirect at all.
在正确实现的 MVC 中, View 实例将包含所有 UI 逻辑。他们将从模型层获取数据(“如何”构成了 Model2、MVP 和 MVVM 之间的大部分差异),决定从哪些模板来组装响应,甚至响应是否需要除 HTTP 位置 header 之外的任何内容。
移动版和桌面版之间的差异将包含在 View 实例中,由 Controller 辅助,在正确的 MVC 结构中, Controller 只会更改模型层和当前 View 的状态。它所做的更改应取决于用户输入。
以下代码将成为 bootstrap.php 或 init.php 的一部分:
// the request instance acts like abstraction for all the user input
$request = new Request;
$request->setUri();
// instantiate the routing mechanism
$router = new Router( new RouteBuilder );
$router->import('/path/to/config.file');
// apply rules from router so that request instance now
// contains the parsed values from URI
$router->route( $request );
// handling of model layer
$serviceFactory = new ServiceFactory;
// since in MVC the controllers are closely tied to views
// (1 controller for 1 view), usually it is convenient to use same class names
$resource = $request->getParameter('resource');
// instantiation of view and controller
$class = '\\View\\' . $resource;
$view = new {$class}( $serviceFactory );
$class = '\\Controller\\' . $resource;
$controller = new {$class}( $serviceFactory, $view);
// i find it convenient to have controller's action be made from
// both REQUEST_METHOD and command name
$action = $request->getMethod() . $request->getParameter('command');
// run it all
$controller->{$action}( $request );
echo $view->render();
这样,当执行命中 Controller 的 Action 时,它会得到一个完全准备好的 Request 实例。该实例决定了用户设备的详细信息,并提供了一个简单的接口(interface)来读取这些详细信息。
Controller 还可以访问模型层和当前 View ,这两者都是通过构造函数注入(inject)的。
最直接的方法是让 Controller 改变当前 View 的状态。
namespace Conroller;
class SomeThing
{
public function getUserDetails( $request )
{
if ( $request->isFromMobile() )
{
$this->view->adjustFor( $request->getDeviceType() );
}
$community = $this->serviceFactory->create('Community');
$community->loadUser( $request->getParameter('id'));
}
}
在这种情况下,adjustFor() 方法通知当前 View 实例,它将需要使用模板,这些模板适用于某些非默认设备。
这种方法有一个非常重要的缺点:它违反了 OCP来自 SOLID 原则(对于懒惰的人:short version),因为如果您决定为现有项目添加移动版本,则必须重写每个 Controller 方法。
虽然下面的代码比较容易理解,但还是有点瑕疵:
$resource = $request->getParameter('resource');
// instantiation of view and controller
$class = '\\View\\' . $resource;
$view = new {$class}( $serviceFactory );
即使您只需要同时提供 HTML 和 JSON/XML 响应,它也会开始崩溃。 View 开始在整个代码中累积相同的重复 IF。这是一个明显的迹象,表明您应该使用 polymorphism ,这些行将是在哪里做的。
除了上面显示的代码,您可以使用类似的代码:
$resource = $request->getParameter('resource');
$class = '\\View\\' . $request->getDeviceType . $resource;
$view = new {$class}( $serviceFactory );
现在,当您拥有移动/桌面应用程序时,您有两个类:\View\DekstopSomething 和 \View\MobileSomething。它们各自可以有独立的逻辑,并从模型层请求完全不同的数据。
与此同时,您的其余代码与输出表单完全分离。
为什么不使用服务器重定向,您最好选择这种方法的几个原因:
您的应用程序独立于服务器软件
并非所有地方都有 Apache(高负载站点通常使用 Nginx 或 Lighttpd),即使您有 Apache,您使用 mod_rewrite 的能力也取决于服务器的配置。
您站点中所有链接的统一方案
无论您在什么设备上使用,查看某些新闻项目的链接总是相同的。它使 URL 的共享和书签变得更加容易。
单点变化
这种方法让您最初为桌面用户创建网站,然后添加移动/平板电脑支持,而无需重写任何现有代码。
You might also be interested in reading two older post on the subject about implementation of model layer and access control in context of MVC.
关于php - 重定向到子域的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14027299/
我想使用spawn(针对多个并发子进程)在Ruby中执行一个外部进程,并将标准输出或标准错误收集到一个字符串中,其方式类似于使用Python的子进程Popen.communicate()可以完成的操作。我尝试将:out/:err重定向到一个新的StringIO对象,但这会生成一个ArgumentError,并且临时重新定义$stdxxx会混淆子进程的输出。 最佳答案 如果你不喜欢popen,这是我的方法:r,w=IO.pipepid=Process.spawn(command,:out=>w,:err=>[:child,:out])
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
我有以下代码#coloursarandomcellwithacorrectcolourdefcolour_random!whiletruedocol,row=rand(columns),rand(rows)cell=self[row,col]ifcell.empty?thencell.should_be_filled??cell.colour!(1):cell.colour!(0)breakendendend做什么并不重要,尽管它应该很明显。关键是Rubocop给了我一个警告Neveruse'do'withmulti-line'while为什么我不应该那样做?那我该怎么办呢?
我为Devise用户和管理员提供了不同的模型。我也在使用Basecamp风格的子域。除了我需要能够以用户或管理员身份进行身份验证的一些Controller和操作外,一切都运行良好。目前我有authenticate_user!在我的application_controller.rb中设置,对于那些只有管理员才能访问的Controller和操作,我使用skip_before_filter跳过它。不幸的是,我不能简单地指定每个Controller的身份验证要求,因为我仍然需要一些Controller和操作才能被用户或管理员访问。我尝试了一些方法都无济于事。看来,如果我移动authentica
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。使用Railsv2.1,假设您有一个可从多个位置访问的Controller的操作。例如,在Rails应用程序中,您有一个链接可以从两个不同的View编辑用户,一个在用户索引View中,另一个在另一个View中(比方说从每个页面上的导航栏)。我想知道根据用户点击的链接将用户重定向回正确位置的最佳方法是什么。例如:示例1:列出所有用户点击列表中用户的“编辑”
我已经解决了标题中描述的错误的众多解决方案。ActionView::Template::Error(缺少要链接的主机!请提供:host参数,设置default_url_options[:host],或将:only_path设置为true):但是,该项目还修改了url_for函数以使用子域,如本railscast所示:http://railscasts.com/episodes/221-subdomains-in-rails-3因此,这个错误的传统答案,例如在我的环境设置中设置变量似乎不是解决方案。这里有一些其他的提示:这是一个全新的设置,我刚刚克隆了一个项目并安装了ruby、rai
我正在使用一个用RubyonRails构建的应用程序,目前错误处理非常差。如果通过ajax执行Controller方法,并且该方法导致500(或404或任何其他响应),则呈现500.html页面并将其作为AJAX请求的结果返回。显然,javascript不知道如何处理该HTML,网页看起来只是在等待响应。在AJAX调用期间发生错误时,rails是否有一种简单的方法来呈现error.rjs模板? 最佳答案 您可以在Controller的rescue_action或rescue_action_in_public方法中使用respond_
我有一个非常具体的问题。我不想进行Controller测试,而是进行请求测试。而且我不想使用Capybara,因为我不想测试用户交互,而只想测试响应状态。我在spec/requests/api/garage_spec.rb下有以下测试require'spec_helper'describe"Garages"dodescribe"index"doit"shouldreturnstatus200"doget'http://api.localhost.dev/garages'response.status.shouldbe(200)response.body.should_notbe_emp
我们想要一个Controller集合,我们将所有操作和下游方法的记录器输出路由到一个单独的日志文件。这是一个Rails3项目。在Rails2中,我们通过重新定义“logger”方法来做到这一点,但在Rails3中,记录的方式是使用“Rails.logger”。我试着把Rails::logger=Logger.new(File.join(Rails.root,'log',"reports_controller.log"),10,1000000)在Controller的顶部,但只有在操作中专门使用Rails.logger的特定情况才会发送到指定的日志文件,Controller的所有默认日志
我正在myrapwebsite上实现全文搜索功能,我遇到了一些关于说唱歌手和歌曲名称的问题。例如,某人可能想使用查询“camron”(省略中间单词撇号)来搜索说唱歌手“Cam'ron”。同样,有人可能会使用查询“3peat”来搜索歌曲“3Peat”。“TheNotoriousB.I.G.”有点奇怪:“TheNotoriousBIG”和“TheNotoriousB.I.G.”两者都有效(我猜是因为solr.StandardFilterFactory从首字母缩略词中删除了点?),但“TheNotoriousB.I.G”(即减去结尾的点)没有。理想情况下,这些名称的所有合理变体都应该有效。我