javascript - 通过 apache 服务器内的服务器端过滤在 SVG 中动态包含 javascript

标签 javascript apache svg matomo

几年前,我编写了一些代码,自动在 http 服务器提供的 html 页面中包含一些 javascript 代码。该方法记录在 blog entry 中在这个 StackOverflow question 。在过去的几年里,这个解决方案对我很有帮助。

两句话的方法:

  • 对于 http 服务器交付的每个完整 html 页面,都会通过服务器端替换将一些占位符添加到页面底部
  • 该占位符再次被通过服务器端包含方式包含的 JavaScript 代码替换

现在我想扩展该解决方案,并将相同的逻辑应用于基于 SVG 而不是 HTML 作为文档格式的页面。注意:不是 html 页面中包含的 SVG,而是可以通过链接直接引用的 SVG 格式的页面。

扩展本身不是问题,JavaScript 代码包含在 SVG 标记内。问题是代码没有被执行。不幸的是,我对 SVG 脚本知之甚少,这就是为什么我有些迷失的原因。也许有人可以给我提示这里出了什么问题:-)

各种 apache vhost 定义中包含的过滤器链:

# ----------
# internal requests to include the piwik tracking code at the bottom of every html page

FilterDeclare PIWIK_token
FilterProvider PIWIK_token SUBSTITUTE resp=Content-Type $text/html
SUBSTITUTE 's|^\s*</body>|<!--#include virtual="/piwik"--></body>|iq'
FilterProvider PIWIK_token SUBSTITUTE resp=Content-Type $image/svg+xml
SUBSTITUTE 's|^\s*</svg>|<!--#include virtual="/piwik"--></svg>|iq'

FilterDeclare PIWIK_code
FilterProvider PIWIK_code INCLUDES resp=Content-Type $text/html
FilterProvider PIWIK_code INCLUDES resp=Content-Type $image/svg+xml

FilterChain PIWIK_token PIWIK_code

# map virtual request to the file system
Alias /piwik /srv/www/internal/piwik.php

# all that is left for the virtual host is to do two things:
#        SetEnv PIWIK_ID 15
#        Include /etc/apache2/vhosts.d/_internal.inc
# note: the '15' above is an example piwik site id

要包含的 JavaScript 代码是 piwik 跟踪代码段的稍微修改版本:

<?php
define('piwikBase','https://some.domain.xxx/stats/');
define('piwikSite',apache_getenv('PIWIK_ID'));
if(is_numeric(piwikSite)){
?>

<script type="text/javascript">
  var _paq = _paq || [];
  _paq.push(["trackPageView"]);
  _paq.push(["enableLinkTracking"]);

  (function() {
    var u="<?= piwikBase ?>";
    _paq.push(["setTrackerUrl", u+"piwik.php"]);
    _paq.push(["setSiteId", "<?= piwikSite ?>"]);
    var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
    g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
  })();
</script>

<?php } else { ?>
<!-- invalid piwik site id: <?php echo piwikSite;?> -->
<?php } ?>

如上所述:扩展有效,JavaScript 代码已成功包含到 SVG 文档中。然而它显然没有被激活,我没有找到原因......

最终交付的 SVG 如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:cc="http://creativecommons.org/ns#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    version="1.2"
    width="100%"
    height="100%"
    viewBox="0 0 640 400"
    docname="somedocument.svg">

[... content of the SVG ...]

<script type="text/javascript">
  var _paq = _paq || [];
  _paq.push(["trackPageView"]);
  _paq.push(["enableLinkTracking"]);

  (function() {
    var u="https://some.domain.xxx/stats/";
    _paq.push(["setTrackerUrl", u+"piwik.php"]);
    _paq.push(["setSiteId", "15"]);
    var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
    g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
  })();
</script>

</svg>

最佳答案

只是猜测,但我会尝试更改代码,以便将动态脚本注入(inject)替换为带有 xlink:href 的内联脚本标记。 (我已经测试过动态地执行此操作,就像您的代码一样,看似“更正确”createAttibuteNS('xlink','href','...'),但结果也没有执行)

生成的代码如下所示(尚未在真实环境中进行测试,因此请注意拼写错误):

<?php
define('piwikBase','https://some.domain.xxx/stats/');
define('piwikSite',apache_getenv('PIWIK_ID'));
if(is_numeric(piwikSite)){
?>
<script type="text/javascript"><![CDATA[
  var _paq = _paq || [];
  _paq.push(["trackPageView"]);
  _paq.push(["enableLinkTracking"]);
  _paq.push(["setTrackerUrl", "<?= piwikBase ?>piwik.php"]);
  _paq.push(["setSiteId", "<?= piwikSite ?>"]);    
]]></script>
<script type="text/javascript"
 xmlns:xlink="http://www.w3.org/1999/xlink"
 xlink:href="<?= piwikBase ?>piwik.js"
 defer="defer" async="async"></script>

<?php } else { ?>
<!-- invalid piwik site id: <?php echo piwikSite;?> -->
<?php } ?>

我不确定那些deferasync东西,它是否对 SVG 有任何影响。我已经使用简单的 datauri 示例对此进行了测试,它似乎运行良好。

注释:

  • xmlns:xlink="http://www.w3.org/1999/xlink"在脚本或它的某些父级上是必要的,但很可能你的 SVG 已经有了它
  • CDATA在这种情况下不是必需的,但如果您打算使用 <& future ……你知道吗。

关于javascript - 通过 apache 服务器内的服务器端过滤在 SVG 中动态包含 javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30896969/

相关文章:

php - UTF-8贯穿始终

bash - 通过一行命令在 Ubuntu 中编辑 conf 文件

php - $_POST 值返回空数组

javascript - 使用 svg 制定自动调整大小的文本框

javascript - 如何修改小脚本以在没有 jquery 的情况下运行

javascript - 将表单的 ID 传递给函数 click() 的参数中

javascript - variableName[0] 有更好的写法吗?

javascript - 从本地文件到网络服务器进行 ajax 调用时不可预测的 javascript 执行顺序

javascript - 旋转椭圆形 SVG 对象

html - 用 tex-anchor : end 包装文本