需求是这样的:在保留protect_from_forgery,不设置action_controller.allow_forgery_protection = false的情况下(也就是依然开启 csrf protection)
protect_from_forgery
action_controller.allow_forgery_protection = false
怎样才能让 rails 的,或者 simple_form 的 form helper 在生成 form 的时候不产生隐藏的 csrf token 字段(这样就能直接对包含 form 的地方用 fragment-cache 了……)
skip_before_filter :verify_authenticity_token
#1 楼 @fresh_fish Well, obviously I DO want to keep verifing authenticity token, but just don't need them in the form
#2 楼 @aptx4869
单个 form 的话加个选项 authenticity_token: false, 所有 form 的话你要自己 hack form helper
authenticity_token: false
另外记得用 javascript 把 token 补上
自己定义个全局的同名 helper 或者可以...
def form_for *xs, **opts, &p super *xs, {authenticity_token: false, **opts}, &p end
#3 楼 @luikore 唔……和我现在干的做法差不多,不过我是对 simple_for_for 包装了一下:
def ng_form_for(record, options={}, &block) options[:authenticity_token] = false simple_form_for(record, options, &block) end
然后因为是在用 angular.js,于是顺便给SimpleForm::Inputs::Base整了个 monkey patch
SimpleForm::Inputs::Base
def initialize(builder, attribute_name, column, input_type, options = {}) ... ... parent_opj_name = builder.object_name.to_s.gsub('[', '.').gsub(']', '').gsub('_attributes', '') @input_html_options[:data] ||={} @input_html_options[:data].merge!({ 'ng-model' => "#{parent_opj_name}.#{attribute_name}"}) end
然后 form 中就自动生成 angularjs 所需的对应 ng-model,然后就再也不用手写前端数据绑定了…… 至于 authenticity_token 部分,angularjs 会自动处理,将 token 丢进 cookies 给它就行了,连 html head 中的 csrf-meta-tag 都能删掉了,然后整个页面就能直接 cache 了……
#4 楼 @luikore 弱问一下,你这里函数定义里面xs, **opts 的几个 * 是啥意思,我看 form_for 和 simple_form_for 的源码里面没用号啊:
def form_for(record, options = {}, &block)
def simple_form_for(record, options={}, &block)
#6 楼 @aptx4869 我没去查原本的签名,就用任意长指定了...
*xs
**opts
js remove 可行吗