2

我必须匹配本地 src 并让它们通过网络加载。例子:

src="/js/my.js">

变成:

src="http://cdn.example.com/js/my.js">

这就是我现在所拥有的:

if (!preg_match("#<script(.+?) src=\"http#i",$page)){ 
$page = preg_replace("#<script(.+?) src=\"#is", "<script$1 src=\"$workingUrl", $page); 
}

当它遇到这样的事情时它工作正常:

<script type='text/javascript' src='/wp-includes/js/jquery/jquery.js?ver=1.8.3'></script>

当它遇到这样的事情时它会失败:

<script language="JavaScript">
window.moveTo(0,0);
window.resizeTo(screen.width,screen.height);
</script>

如果脚本标签不包含 src,它将找到第一个图像标签的 src 并切换其 URL。

我需要知道如何让它仅终止脚本标签上的匹配和/或如何更好地执行替换。

4

2 回答 2

2

除非使用 DOMDocument::loadHTML 并改用 DOM,否则不要使用 . 并且只接受第一个 > 之前的所有内容作为后备可能会更好(尽管并不完美,因为在理论上可能存在包含 > 的 <script> 的其他属性)。

使用:

#<script([^>]+?) src=\"#is

因为您的模式反而使模式在遇到 <script 之后的第一个 > 时停止匹配。

于 2013-01-10T13:15:08.890 回答
2

绝对使用 DOM 解析器。带有 DOMDocument 的 Xpath 将干净、可靠地替换以下脚本标记:

  1. 有一个 src 属性和
  2. src 属性不以 http 开头。

我本可以进一步开发 xpath 查询表达式来检查前导http子字符串,但我不想用更多语法吓跑你。

代码:(演示

$html = <<<HTML
<html>
<head>
<script type='text/javascript' src='/wp-includes/js/jquery/jquery.js?ver=1.8.3'></script>
<script language="JavaScript">
window.moveTo(0,0);
window.resizeTo(screen.width,screen.height);
</script>
</head>
</html>
HTML;

$workingUrl = 'https://www.example.com';

$dom = new DOMDocument; 
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//script[@src]") as $node) {
    if (strpos($node->getAttribute('src'), 'http') !== 0) {
        $node->setAttribute('src', $workingUrl);        
    }
}
echo $dom->saveHTML();

输出:

<html>
<head>
<script type="text/javascript" src="https://www.example.com"></script>
<script language="JavaScript">
window.moveTo(0,0);
window.resizeTo(screen.width,screen.height);
</script>
</head>
</html>

唯一稍微“吓人”的 xpath 版本:(演示

$dom = new DOMDocument; 
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//script[@src and not(starts-with(@src,'http'))]") as $node) {
    $node->setAttribute('src', $workingUrl);        
}
echo $dom->saveHTML();
于 2019-11-22T08:44:03.760 回答