几年前,我编写了一些代码,自动在 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 } ?>
我不确定那些defer
和async
东西,它是否对 SVG 有任何影响。我已经使用简单的 datauri 示例对此进行了测试,它似乎运行良好。
注释:
-
xmlns:xlink="http://www.w3.org/1999/xlink"
在脚本或它的某些父级上是必要的,但很可能你的 SVG 已经有了它 -
CDATA
在这种情况下不是必需的,但如果您打算使用<
或&
future ……你知道吗。
关于javascript - 通过 apache 服务器内的服务器端过滤在 SVG 中动态包含 javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30896969/