Ruby小问题

Ruby中的小问题,放在这里备查。

0、

打出当前调用栈: puts caller

1、

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken)

原理是rails为了防止伪造当前web程序的链接,技术上是嵌入一个随机字符串在会话中,这样攻击者无法知道,保证了不会有通过其他网站控制器从CSRF的攻击行动。

解决方法是为请求加一个参数:参数名是<%=request_forgery_protection_token.to_s%>,值是<%=form_authenticity_token.to_s%>

若用form提交,可在form中加入

<%= tag(:input:type => "hidden":name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %>

若用ajax提交,可在参数中加入"<%=request_forgery_protection_token.to_s%>=<%=form_authenticity_token.to_s%>"

2、

在controller中使用Thread.current[:some_key] = 'some value'时,可能会引发严重的数据和权限问题,解决办法是after_filter中Thread.current[:some_key] = nil

3、

从GET请求的url中获取参数:

params = HashWithIndifferentAccess.new Rack::Utils.parse_nested_query("a=1&b=2") # => {"a"=>"1", "b"=>"2"}

Rails中间件中获取请求参数:
    params = {}
    params = params.merge(env["rack.request.query_hash"]) if env["rack.request.query_hash"].present? # 来自url
    params = params.merge(env['rack.request.form_hash']) if env['rack.request.form_hash'].present? # 来自post请求
    params = params.merge(env["action_dispatch.request.request_parameters"]) if env["action_dispatch.request.request_parameters"].present? # 来自post请求,并且contentType: "application/json"

4、

输出cookies:

logger.debug cookies.instance_variable_get(:@cookies).to_s

Rails的session验证机制

_session, ver = _session_id.split('--')

_session = CGI::unescape(_session)

#==========active_support/message_verifier.rb

generate_digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get('SHA1').new, secret, _session)

unless ver == generate_digest

  raise ActiveSupport::MessageVerifier::InvalidSignature

end

cookie中的_session_id在rails后台转变成session

Marshal.load(Base64.decode64("_session_id"))

5、

windows.office2010生成的xlsx文件作为附件,用rails发送email,会出现exception:

"exception"=>"ArgumentError", "error"=>"invalid byte sequence in UTF-8"

/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.2/lib/active_support/core_ext/object/blank.rb:105:in `=~'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.2/lib/active_support/core_ext/object/blank.rb:105:in `!~'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.2.2/lib/active_support/core_ext/object/blank.rb:105:in `blank?'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/body.rb:36:in `initialize'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/message.rb:1909:in `new'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/message.rb:1909:in `process_body_raw'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/message.rb:1155:in `body'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/message.rb:2000:in `init_with_hash'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/message.rb:123:in `initialize'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/attachments_list.rb:78:in `new'
/home/zzq/.rvm/gems/ruby-1.9.2-p320/gems/mail-2.4.4/lib/mail/attachments_list.rb:78:in `[]='

出错行如下:

attachments[filename] = File.read(filepath)

解决办法:

attachments[filename] = {:content => File.read(filepath, :mode => 'rb'), :transfer_encoding => :binary}

6、

mysql5.5前不支持utf8mb4,mb4字符不会出现在数据库中,为了解决这个问题,将mysql升级后,rails中生成json还有问题。

解决办法:增加文件:config/initializers/active_support_encoding.rb

内容:

module ActiveSupport::JSON::Encoding
    class << self
        def escape(string)
            if string.respond_to?(:force_encoding)
                string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
            end
            json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }
            json = %("#{json}")
            json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
            json
        end
    end
end

7、

如何使用X-Accel_Redirect?

X-Accel_Redirect是nginx的功能,可以支持从文件系统直接读取文件发送到客户端,跳过应用服务器,提高效率。

在nginx配置中加入:http{server{

location /file-internal {
  internal;#只接收内部请求,防止外部请求直接访问
  alias /your/file/path;
}

}}

在下载action中,不用send_file,用这一句:

return head(:x_accel_redirect => '/file-internal/1.jpg',:content_disposition => "attachment; filename=\"1.jpg\"",'Content-Type'=>'image/jpeg')

nginx收到后,会将/your/file/path/1.jpg发送给客户端。

8、

使用mongoid时,在rails console中输出数据库查询语句:

Mongoid.logger.instance_variable_set('@log', $stdout)

9、

遍历文件夹:

1).仅遍历当前文件夹

Dir.foreach('/tmp') do |filename|

if filename != "." and filename != ".."

2). 遍历所有子孙文件夹

require 'find'

Find.find("/tmp") do |filename|

File.directory?(filename)

3). 批量修改文件编码

utf8转gbk:


require 'find'

arr = ["path"]
arr.each do |rep|
Find.find("D:\\apps\\#{rep}") do |filename|

if !File.directory?(filename) && (filename.ends_with?('.txt'))
f1 = File.open(filename, 'r')
s1 = f1.read
f1.close
#s2 = s1.encode('utf-8','gbk',{:invalid => :replace, :undef => :replace, :replace => '?'})
s2 = s1.encode('gbk','utf-8')
f2 = File.open(filename, 'w:gbk')
f2.puts s2
f2.close
end
end
end

10、

字符串转换为url参数:

ERB::Util.url_encode("@/\\") #=> "%40%2F%5C"

URI.encode("@/\\") #=> "@/%5C"

URI.decode("%40%2F%5C") #=> "@/\\"

11、

linux下生成的csv在windows下office excel乱码问题:

csv_bom = "\377\376"
filename = 'test.csv'
file = File.open(filename, 'w')
file.write csv_bom
file.close
file = File.open(filename, "a:UTF-16LE")
file.puts "列一\t列二"
file.puts "1\t2"
file.close

12、

ie中下载文件乱码,chrome、firefox不乱码问题:

user_agent = request.env['HTTP_USER_AGENT'].downcase
_filename = user_agent.include?("msie") ?  ERB::Util.url_encode(File.basename(filename)) : File.basename(filename)
send_file(filename, :filename => _filename)

13、

在linux上用zip生成.zip文件,在windows上用winzip解压后,文件名乱码问题。(用好压解压不乱码)

原因是linux上的zip压缩时没有标明文件名编码,默认是UTF-8,而winzip默认为ANSI。

解决办法:

1、安装7z,sudo apt-get install p7zip-full

2、压缩命令由原(zip -r zip.zip *),修改为新(7z a -r -t7z 7z.zip *)

参考:http://frank19900731.github.io/blog/2015/02/11/jie-jue-mac-xia-zip-ya-suo-wen-jian-zai-windows-xia-xian-shi-luan-ma-de-wen-ti/

14、

arr=str.scan(/[0-9]{18}/)

原文地址:https://www.cnblogs.com/zycjwdss/p/1868757.html