【发布时间】:2018-07-27 22:10:41
【问题描述】:
我已经看到了一些答案(例如this one),但我有一些更复杂的情况我不知道如何解释。
我基本上拥有完整的 HTML 文档。我需要用绝对 URL 替换每个相对 URL。
潜在 HTML 中的元素如下所示,也可能是其他情况:
<img src="/relative/url/img.jpg" />
<form action="/">
<form action="/contact-us/">
<a href='/relative/url/'>Note the Single Quote</a>
<img src="//example.com/protocol-relative-img.jpg" />
期望的输出是:
// "//example.com/" is ideal, but "http(s)://example.com/" are acceptable
<img src="//example.com/relative/url/img.jpg" />
<form action="//example.com/">
<form action="//example.com/contact-us/">
<a href='//example.com/relative/url/'>Note the Single Quote</a>
<img src="//example.com/protocol-relative-img.jpg" /> <!-- Unmodified -->
我不想替换协议相对 URL,因为它们已经充当绝对 URL。我想出了一些有效的代码,但我想知道是否可以稍微清理一下,因为它非常重复。
但我必须考虑 src、href 和 action 的单引号和双引号属性值(我是否遗漏了任何可以具有相对 URL 的属性?)同时避免协议相对 URL。
这是我目前所拥有的:
// Make URL replacement protocol relative to not break insecure/secure links
$url = str_replace( array( 'http://', 'https://' ), '//', $url );
// Temporarily Modify Protocol-Relative URLS
$str = str_replace( 'src="//', 'src="::TEMP_REPLACE::', $str );
$str = str_replace( "src='//", "src='::TEMP_REPLACE::", $str );
$str = str_replace( 'href="//', 'href="::TEMP_REPLACE::', $str );
$str = str_replace( "href='//", "href='::TEMP_REPLACE::", $str );
$str = str_replace( 'action="//', 'action="::TEMP_REPLACE::', $str );
$str = str_replace( "action='//", "action='::TEMP_REPLACE::", $str );
// Replace all other Relative URLS
$str = str_replace( 'src="/', 'src="'. $url .'/', $str );
$str = str_replace( "src='/", "src='". $url ."/", $str );
$str = str_replace( 'href="/', 'href="'. $url .'/', $str );
$str = str_replace( "href='/", "href='". $url ."/", $str );
$str = str_replace( 'action="/', 'action="'. $url .'/', $str );
$str = str_replace( "action='/", "action='". $url ."/", $str );
// Change Protocol Relative URLs back
$str = str_replace( 'src="::TEMP_REPLACE::', 'src="//', $str );
$str = str_replace( "src='::TEMP_REPLACE::", "src='//", $str );
$str = str_replace( 'href="::TEMP_REPLACE::', 'href="//', $str );
$str = str_replace( "href='::TEMP_REPLACE::", "href='//", $str );
$str = str_replace( 'action="::TEMP_REPLACE::', 'action="//', $str );
$str = str_replace( "action='::TEMP_REPLACE::", "action='//", $str );
我的意思是,它有效,但它uuugly,我在想可能有更好的方法来做到这一点。
【问题讨论】:
-
为什么,绝对网址不能很好地传播
-
我知道这很不寻常,不幸的是在这个 one 特殊情况下,它们比相对 URL 传播得更好。为了争论,我有一个存在并在
https://example.com/contact进行自我验证的表单,默认标签是<form action="/contact">可以正常工作,但是我们的客户需要将此内容1:1 克隆到另一个URL,其中/contact没有'不存在或没有验证,因此表单将在提交时出现 404 或不验证。与链接相同。我知道这是不典型的,但对于这个项目,绝对 URL 更适合它。 -
您是否要更改一堆 php 文件中的所有引用?如果是这样,基于 Perl 命令行的正则表达式可能会很好地工作: perl -p -i.bak -e 's/search/replace/g' *.php
-
不,不幸的是,这是一个客户端应用程序。目前最常见的用例是我们的网站客户端使用 WordPress 网站。我们还有一个专有的登陆页面生成软件。一些客户希望他们的目标网页与他们的网站共享相同的 URL(巨大的争用点)。如果不设置域映射(我们不控制所有托管),我们需要将它们的内容带过来。所以我写了一个插件来终止原始请求,并将其替换为新 URL 中的内容。它真的很好用,除了......
-
...当有相对 URL 时,尤其是表单和图像。我有另一种方法可以在内容中使用 iframe,但它可以工作,但挑剔的客户不希望它 iframe(哈哈?),以及 301 重定向的第三个选项,但它否定了整个“相同的 URL”部分。下载效果最好,因为我可以缓存响应,并且上面的代码 works 可以一路替换相对 URL,只是想知道是否有更好的方法,而不是 18 个后续的
str_replace()函数。跨度>
标签: php url str-replace relative-path absolute-path