ruby - URI.escape 的简单替代方案
问题描述
在 URL 上使用URI.parse
时,我遇到了一条错误消息:
URI::InvalidURIError: URI must be ascii only
我发现了一个建议使用的 StackOverflow 问题URI.escape
,它有效。以该问题中的 URL 为例:
URI.parse('http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg')
=> URI::InvalidURIError: URI must be ascii only "http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/\u041E\u0443\u044D\u043D-\u041C\u044D\u0442\u044C\u044E\u0441.jpg"
URI.encode('http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg')
=> "http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/%D0%9E%D1%83%D1%8D%D0%BD-%D0%9C%D1%8D%D1%82%D1%8C%D1%8E%D1%81.jpg"
但是,URI.escape
正如Rubocop警告的那样,它已经过时了:
URI.escape method is obsolete and should not be used. Instead, use CGI.escape, URI.encode_www_form or URI.encode_www_form_component depending on your specific use case.
但是,虽然URI.escape
给了我们一个可用的结果,但替代方案不会:
CGI.escape('http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg')
=> "http%3A%2F%2Fdxczjjuegupb.cloudfront.net%2Fwp-content%2Fuploads%2F2017%2F10%2F%D0%9E%D1%83%D1%8D%D0%BD-%D0%9C%D1%8D%D1%82%D1%8C%D1%8E%D1%81.jpg"
这很麻烦,因为在我的情况下,我正在从通过Nokogiri获得的数据构建一个 URL :
my_url = page.at('.someclass').at('img').attr('src')
由于我只需要转义生成的 URL 的最后一部分,但CGI.escape
类似地转换整个字符串(包括必要的字符,例如:
and /
),现在获得转义的结果变成了多行代码的考验,不得不拆分路径并使用多个变量来实现以前使用单个函数 ( URI.escape
) 可以完成的任务。
有没有我没有看到的简单替代方案?它需要在没有外部宝石的情况下完成。
解决方案
我倾向于使用Addressable
解析 URL,因为该标准URI
存在缺陷:
require 'addressable'
Addressable::URI.parse('http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg')
#<Addressable::URI:0x3fc37ecc1c40 URI:http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg>
Addressable::URI.parse('http://dxczjjuegupb.cloudfront.net/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg').path
# "/wp-content/uploads/2017/10/Оуэн-Мэтьюс.jpg"
它不是 Ruby 核心或标准库的一部分,但它应该是并且它总是以我Gemfile
的 s.
推荐阅读
- java - 根据用户输入中出现的字符从包含字母的数组列表中删除字符
- python - 如何在 python 中的稀疏矩阵上应用 colamd 算法?
- react-native - React useEffect 引发“创建不是函数”错误
- java - 在 Optional 中包装数据类型导致的 ClassCastException
- kubernetes - Kubernetes:将本地文件夹挂载到 pod 时出现问题 - “0/1 个节点可用:1 个节点发生卷节点关联性冲突。”
- mongodb - 如何在一个聚合管道阶段进行计数并在稍后阶段使用它?
- asp.net - 如何从 Web API 获取数据到 Xamarin 表单选择器?
- javascript - Get Timer ID in Node.js
- ruby-on-rails - Ruby on Rails 表单错误未提供任何输出/不工作
- django - 如何在模板中的 if 语句中保持模式打开