控制器内部对请求的操作


原文:http://xf986321.iteye.com/blog/495994

控制器内部对请求的操作 
一Action方法 
1调用方式 
控制器处理请求时会找到与之名字匹配的action. 
调用method_missing(),如果找不到action 
调用模版,如果找不到action和method_missing() 
调用错误报告Unknown Action如果上述都不符合 
2禁止调用 
将action声明为protected或private,也可以不改变私有性声明为hidden_action :XXX 
3控制器环境 
action_name 当前处理的action名称 
cookies与请求相关的cookie,相应时对象设置的值将保存到客户机上 
headers一个类似于hash的对象,代表HTTP头信息,这些信息用于应答 
params一个类似于hash的对象,存放着请求参数 
request进入控制器的请求对象,包含属性: 
domain 返回请求地址中域名部分的最后两段 
remote_ip一字符串形式返回客户端IP,若有代理则包含多个IP地址 
env返回客户浏览器设置的环境变量值如:request.env[‘XXX’] 
method返回客户端所使用的请求方法:delete,put,get,post…. 
delete?,get?,head?,post?,put?返回是否为该方法:true or false 
xml_http_request?和xhr?,请求来自AJAX则返回true 与method值无关 
response代表HTTP应答的对象,在处理时rails填充这个对象 
session一个类似与hash的对象,代表当前的session数据 
4应答 
模版的渲染(render:) 
Rails内建支持3中模版:.rhtml格式内嵌ruby代码的HTML代码;构造器XML内容的方式;rjs,用于生成JavaScript 
通过定义ActionController::Base.template_root=dir_path改变视图根路径,默认的视图根路径为:app/views 
render(:text=>string)将指定字符串发送给客户端 
render(:inline=>string,:type=>”rhtml”/”rxml”/”rjs”,:locals=>hash)把string内容作为指定的type模版进行渲染,:locals提供局部模版中的变量 
render(:action=>action_name,:locals=>hash)渲染控制器中指定的action对应的模版 
render(:file=>path,:use_full_path=>true/false,:locals=>hash)渲染指定路径的模版, 若设置:use_full_path=>true,则变为相对路径的方式寻找 
render(:template=>name)  template必须同事包含控制器名和action名 
render(:partial=>name)  渲染一个局部模版 
render(:js=>”alert(‘xxx’)”) 将返回text/javascript格式 
render(:nothing=>true)  什么都不返回---返回一片空白给浏览器 
render(:xml=>stuff)  以xml格式渲染,stuff将被强制转换为xml格式 
render(:json=>stuff)  以json格式渲染,stuff将被强制转换为json格式 
render(:update) do |page| …end以rjs模版渲染 从略 
文件下载(send_data,send_file) 
send_data(data, options)发送一个二进制数据流给客户端 
send_file(path, options)发送一个文件内容给客户端 
重定向(redirect_to) 
Redirect_to(:action, options)options可以提供params的值 
Redirect_to(:back)返回前一个action 
5 cookie和session 
cookie 
cookie的创建:cookie的值必须是字符串 
Cookies[:name]={:value=>值,:domain=>”http://www.xxx.com”,:path=>”/store”,: expires =>””,:secure=>”secure”/”空串” } 
domain属性用来设置所定义的Cookie变量的域,设置不同变量的域可以防止不同网站之间的Cookie相互冲突 
path属性用来设置所定义的Cookie变量的文件路径,请求为此路径时cookie才有效 
expires属性来设置它的生命期限。 
secure属性为secure或为空,WEB服务器之间就通过HTTPS或者其它安全协议传递数据 
session 
与cookie不同session是保存在服务器端的。建立会话后应用会为session分配一个session_id,他将保存在cookie中以便用户对session的访问以及修改 
Session中可以保存任意可以被序列化的对象。存储ActiveRecord对象需在控制器中加入声明——model : session的键,在声明的控制器引用session便可为模型对象进行序列化和反序列化的操作 
1)Session自定义属性:可在config/environment中设置config.action_controller.session.option的hash 
:session_domain 用于保存session_id的cookie作用域,默认为当前应用域名 
:session_id如果不设置此项,新建session会自动得到一个32字长的id 
:session_key用于保存session id的cookie名称 
:session_path有效的路径范围。默认值是/,既整个域名内有效 
:session_secure如果设为true,则只有当用http://开头的地址访问时session生效 
2)Session的存储 
在config/environment中设置config.active_record.session_store的值来指定存储机制,这个值由CGI::Session模块中定义,除PStore与默认的cookiestore,其他存储策略直接符号引用 
session_store=CGI::Session:PStore方式 
数据保存到PStore格式的文件中,2.x后被遗弃的方式 
session_store=:active_record_store 
数据保存到数据库,通过rake db:sessions:create建立session表迁移任务。2.x后开启此模式若同时需要csrf保护,需要设置csrf密钥 
session_store=:drb_store 
数据保存到非web应用之外的服务器(而通过服务器这些数据又可以存储到不同的物理位置,google采用了这种水平伸缩的吞吐) 
其他存储方式是不推荐作为B/S架构的存储方式。 
3)session的过期 
人工session过期可以使用reset_session(),是一种主动清除的策略;如果采用非cookiestore可以服务器删除过期session的策略 
Flash 
Flash有session类似的功能,区别在于flash所记忆的内容只能提供给跳转后的下一个action,所以我经常把flash又叫做小session 
Flash的两个方法: 
flash.now[:key]=value此flash将能通过跳转传到下个action 
成功跳转后在跳转后的action定义:flash.keep[:key]=value将保持传递性,将再传递到下一个action,从而实现了2次跳转仍然保持原数据。 
6过滤器与校验 
1)前置、后置、环绕过滤 
before_filter:     前置 
after_filter:  后置 
around_filter: 环绕 
注:一个controller中有多个前置、后置过滤器时,加入一个前置或后置过滤都将会添加到所有以添加的过滤器后,既先执行其他过滤后在执行 新加入的前置或后置过滤。若希望新加入的先被执行则前置:prepend_before_filter,后置:prepend_after_filter 
环绕过滤与上述不同,当controller中有多个环绕过滤时,新加入的环绕则嵌套在其他环绕过滤中,就如同大家见过的嵌套循环的结构一样 
2)过滤形式 
过滤方法:定义一个过滤方法通过xxx_filter: method引用,注:环绕过滤内部要用yield引入要执行的action 
过滤模块:  xxx_filter do |some_params| 
some_params为控制器参数 
end 
注:环绕过滤还要传入另一个参数,该参数的call方法将执行过滤的action 
过滤类:定义一个类,并创建类方法filter(some_params),过滤声明为xxx_filter 类, 
当过滤器被调用,则类的filter方法被调用,并传入控制器参数。注:环绕过滤需要在filter类方法中定义yield 
3)过滤的有效范围 
xxx_filter:some_method,:only=>[:one_action,:two_action]指定需要过滤的action 
xxx_filter:some_method,:except=>[:one_action,:two_action]指定不需要过滤的action 
4)rails提供的内置过滤校验 
例: 
verify :only=> :some_action  #需要过滤验证的内容 
:session=>:some_key  #判断会话中有some_key的键值 
:add_flash=>{:note=>”some_noties”} #上个条件不成立flash添加此信息 
:redirect=>:some_action #条件不成立跳转的action 
有效范围 :only=> :some_action 需要过滤的action 
:except=> :some_action 不需要过滤的action 
检查条件 :flash=>:key  #flash中是否包含指定的键 
:method=>:symbol  #请求方法(get、post、put等) 
:params=>:key  #请求参数中包含指定的键 
:session=>:key  #session中是否包含指定的键 
:xhr=>true or false  #请求是否来自AJAX 
动作 :add_flash=>hash  #将指定的hash放入flash 
:add_headers=>hash  #应答头信息放入hash的内容 
:redirect_to=>url_for,params  #根据条件跳转 
:render=>params  #根据条件渲染模版 
7缓存处理 
三种缓存机制: 
页面缓存:将整个渲染后的页面放入缓存,后续调用直接调用缓存 
Action缓存:需经过filter后将action放入缓存,后续访问通过过滤后若有此 
缓存,则直接调用缓存 
片段缓存:后面介绍 
1)缓存钩子(控制器中) 
caches_page :some_action  #设定某个action的页面缓存 
caches_action :some_action  #设定某个action的action缓存 
注:缓存只要在生产模式被开启,手动设置为在environement.rb中设置 
config.action_controller.perform_caching=true,这里特别要注意,不是所有内容都能缓存,对于可变性很大的内容最好不要缓存,这个需要根据开发经验而定 
2)手工清除缓存 
缓存的内容被更新后,对于用户缓存的内容没有任何意义,并且没用的缓存会占用大量的资源。 
expire_page :some_action  #清除指定action的页面缓存 
expire_action :some_action  #清除指定action的页面缓存 
3)缓存清扫器 
人工清理缓存对于大型项目势必要漏清,这里引入清理器,清扫器应该放在model下 
class SomeModelSweeper < ActionController::Caching::Sweeper 
observe Article  #设置要监视的模型 
#表中添加新数据后执行页面缓存清理 
def after_create(article) 
expire_public_page 
end 
#表中数据被更新后执行action缓存清理 
def after_update(article) 
expire_article_page(article.id) 
end 
#表中数据被删除一条或多条时同事执行页面、action缓存清理 
def after_destroy(article) 
expire_public_page 
expire_article_page(article.id) 
end 
private 
def expire_public_page 
expire_page(:controller => "content" , :action => 'public_content' ) 
end 
def expire_article_page(article_id) 
expire_action(:controller => "content" , 
:action => "premium_content" , 
:id => article_id) 
end 
end 
控制器中的清理器钩子(在控制器中) 
cache_sweeper :article_sweeper,   #开启Article清理器 
:onlye=>:some_action  #监视的控制器 
:except=>:some_action  #忽略的控制器 
注:若要对可变性较大内容进行缓存需要引入时间缓存失效策略:通过操作系统编写定时删除缓存的进程来控制 
8CSRF安全策略 
Rails2.x后引入了防止跨域访问攻击的pluging,具体操作如下 
在控制器中定义protect_from_forgery钩子,在模版中使用form_for等标签时,服务器会在生成form_for等标签时 建立一个密钥(token),服务器会监视request回来的所有post以及AJAX行为,如果request没有token或者与服务器计算出的不 一致,将返回错误信息。 
cookiestore的session存储机制下,token是根据CGI::Session.generate_unique_id生成的随即数并进行编码得到的,所以不需要为protect_from_forgery设置secret的键值 
:active_record_store是根据session_id、protect_from_forgery的secret的值以及digest(默认是SHA1)计算得来,所以要为这种session机制设置secret值。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值