【问题标题】:How to replace relative path URLs with absolute path URLs如何用绝对路径 URL 替换相对路径 URL
【发布时间】:2013-04-08 20:36:05
【问题描述】:

我将 HTML 内容存储在数据库中,我希望将所有相对资产引用转换为使用绝对路径。例如,我所有的图片标签都是这样的:

<img src=\"/system/images/146/original/03.png?1362691463\">

我正在尝试将 "http://example.com" 添加到 "/system/images/" 路径。我有以下代码,我希望能处理它,但遗憾的是它似乎并没有导致任何变化:

text = "<img src=\"/system/images/146/original/03.png?1362691463\">"
text.gsub(%r{<img src=\\('|")\/system\/images\/}, "<img src=\"http://virtualrobotgames.com/system/images/")

【问题讨论】:

  • 您应该考虑使用专门为这项工作设计的工具:URI。它具有解析 URL、更改方案和主机、弄乱路径、然后吐出一个所有内容都正确编码的字符串的方法。
  • @theTinMan 我喜欢这个主意,如果你把它改写为答案,我很乐意接受。
  • 我添加了一个扩展示例。

标签: ruby-on-rails ruby


【解决方案1】:

不要使用普通的字符串操作来操作 URL 字符串,而是使用专为这项工作设计的工具。 Ruby 包含 URI 类,还有更彻底的 Addressable gem。

如果我有一些带有我想重写的链接的 HTML,我会这样做:

首先,解析文档:

require 'nokogiri'
require 'uri'

SOURCE_SITE = URI.parse("http://virtualrobotgames.com")

html = '
<html>
<head></head>
<body>
  <img src="/system/images/146/original/03.png?1362691463">
  <script src="/scripts/foo.js"></script>
  <a href="/foo/bar.html">foo</a>
</body>
</html>
'
doc = Nokogiri::HTML(html)

然后您就可以浏览文档并修改&lt;a&gt;&lt;img&gt;&lt;script&gt; 等标签以及您想要的任何其他内容:

# find things using 'src' and 'href' parameters
tags = {
  'img'    => 'src',
  'script' => 'src',
  'a'      => 'href'
}
doc.search(tags.keys.join(',')).each do |node|

  url_param = tags[node.name]

  src = node[url_param]
  unless (src.empty?)
    uri = URI.parse(src)
    unless uri.host
      uri.scheme = SOURCE_SITE.scheme
      uri.host = SOURCE_SITE.host
      node[url_param] = uri.to_s
    end
  end
end

puts doc.to_html

运行后输出:

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html>
# >> <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
# >> <body>
# >>   <img src="http://virtualrobotgames.com/system/images/146/original/03.png?1362691463">
# >>   <script src="http://virtualrobotgames.com/scripts/foo.js"></script>
# >>   <a href="http://virtualrobotgames.com/foo/bar.html">foo</a>
# >> </body>
# >> </html>

这并不意味着是一个完整、完整的示例。这适用于绝对链接,但您必须处理相对链接、具有同级/对等主机名的链接、缺少参数。

您还需要在解析后检查“doc”的errors 方法,以确保它是有效的 HTML。解析器可以重写/修剪无效 HTML 中的节点以试图理解它。

【讨论】:

  • 你不能在字符串上调用 URI 方法,必须是 URI(SOURCE_SITE).scheme
  • 只获取body标签内的html,使用doc.at('body').inner_html
  • @Sidhannowe,这就是代码使用 uri = URI.parse(src) 的原因,它将字符串解析为 URI 对象。
  • @theTinMan 谢谢你,你的回答帮助我快速做一些非常相似的事情。 @Sidhannowe 是对的,代码声明了 uri,但试图在声明 url 的字符串(变量 source_site)上调用 schemehost。我编辑了代码。
  • 不要在人们的答案中编辑代码。这歪曲了他们所说的。欢迎您发表评论或添加一个单独的答案来证明差异。似乎有几个人编辑了它,修改错误。我会解决的。
【解决方案2】:

你不能只使用'base' HTML 标记来执行此操作吗?假设您直接从 URL 读取 HTML 内容,您可以执行以下操作:

response = RestClient.get(<original_url>)
base_url = '<your_base_url>'
html_content = response.body
if html_content.index('<head>')
    html_content = html_content.gsub!('<head>', "<head><base href='#{base_url}'>")
end

【讨论】:

    【解决方案3】:

    显然这是我传递的搜索参数的问题,不需要转义序列。

    %r{<img src=\\('|")\/system\/images\/}
    

    变得简单:

    %r{<img src="/system/images/}
    

    【讨论】:

      猜你喜欢
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 2010-10-03
      • 2011-11-15
      相关资源
      最近更新 更多