Rails 这种 URL 特殊字符如何处理?

xiaobai2 · 2018年05月07日 · 最后由 xiaobai2 回复于 2018年05月07日 · 2381 次阅读

业务场景是一个翻译功能,集成了百度翻译的 sdk API 如下:

HTTParty.get("#{url}?appid=#{app_id}&q=#{q}&from=#{from}&to=#{to}&salt=#{salt}&sign=#{sign}")

q 是我要翻译的原文。from 是翻译源语言,to 是译文语言,salt 是随机数,sign 是这些参数经过 MD5 的验签。 问题就出在了参数 q 上! 假如 q 里面包含特殊字符“+”,比如 q=“我是 + 小强”url 将会是

http://api.fanyi.baidu.com/api/trans/vip/translate?q=我是+小强&from=en&to=zh&appid=2015063000000001&salt=1435660288&sign=f89f9594663708c1605f3d736d01d2d4

我的意愿是将翻译成:I'm a + little strong 但就是 url 里面这个特殊字符导致签名过不去,我改怎么处理? 追加:这个应该和签名没关系,主要原因是我 url 里暴露了非法的特殊字符导致的

adamshen 回复

求指点,每太看懂 😂

正确姿势:

request_params = { appid: app_id, q: q, from: from, to: to, salt: salt, sign: sign }
HTTParty.get("#{url}?#{request_params.to_query}")

http://api.rubyonrails.org/classes/Hash.html#method-i-to_query

huacnlee 回复

可是这个还没解决 url 里面有特殊字符的情况啊😆

q = URI.encode_www_form_component('我是+小强')

再去签 sign 试试

你那么传,估计百度把你的 + 当空格处理了

代码大概是如下

q          = URI::encode(q) # encode
      q          = URI.encode_www_form_component(q)
      sign       = Digest::MD5.hexdigest("#{app_id}#{q}#{salt}#{secret_key}") # 签名
      begin
        request_params = { appid: app_id, q: q, from: from, to: to, salt: salt, sign: sign }
        result = HTTParty.get("#{url}?#{request_params.to_query}")
        error_code = result.parsed_response['error_code']
        if error_code.blank?
          result['trans_result'][0]['dst'] # 如果正确返回译文结果
        else
          error = "#{error_code}: #{ERROR_LIST[error_code.to_i]}"
        end
      rescue URI::InvalidURIError
        raise error
      end

按照你说的加了一层 filter 现在翻译的结果是这样😂

"25e6 % % % % % 25e6 2588 2591 2598 25af % % % % % 25b0 2B 25e5 258f 25e5 % % % 25bc 25ba"

我再想是否换成 post 请求不把特殊字符暴露在 url 里就可以了?

xiaobai2 回复

呃 你这完全乱了,encode 两次了,不过刚刚我的回复也是错的

应该是签名的时候用「我是 + 小强」,url 里面传「我是%2B 小强」

这样应该就对了

q = "我是+小强"
sign = Digest::MD5.hexdigest("#{app_id}#{q}#{salt}#{secret_key}")
request_params = { appid: app_id, q: q, from: from, to: to, salt: salt, sign: sign }
result = HTTParty.get("#{url}?#{request_params.to_query}")

@huacnlee 的就是正确答案

IChou 回复

@huacnlee @IChou 明白,谢谢了。不胜感激😀

需要 登录 后方可回复, 如果你还没有账号请 注册新账号