被这个问题折腾得够呛,本来是希望在 Gitea 中使用 GTM,但发现怎么都配置不上,并且会导致 Gitea 前端的完全失效。
从截图看,问题已经比较明确:Gitea 本身的 JavaScript 并没有坏,主要是你加入的 GTM / Google Tag 代码违反了 Gitea 当前的 Content Security Policy (CSP),导致浏览器阻止 inline script 执行。
截图里最关键的是:
Executing inline script violates the following Content Security Policy directive 'script-src ...'
Either the 'unsafe-inline' keyword, a hash (...) or a nonce (...) is required
The action has been blocked.
上面的配置会导致:
error: Gitea JavaScript code couldn't run correctly, please check your custom templates
这个错误,虽然是这个错误,但实际上不是模板的问题。
调试后,发现 CF 的预加载 Tag 管理的时候,因为 CSP 的问题导致 Gitea 的前端全部失效。
这是 CSP(Content Security Policy)阻止了 Google Tag Manager 加载后的 inline script 执行,不是 GTM Container ID 本身的问题。
直接使用 GTM 的问题
从截图看,错误已经很明确了:不是缓存问题,而是 CSP Nonce 不匹配导致 GTM 的 inline script 被浏览器拦截。
你页面里 Gitea 自己的脚本带了 nonce:
<script nonce="c92794dc25088d64ef3706325643a422"
src="/assets/js/iife.D2XhYhS2.js"></script>
但你后面加入的 GTM:
<script>
(function(w,d,s,l,i){ ... })
</script>
没有 nonce。
而浏览器收到的 CSP 大致是:
script-src 'nonce-c92794dc25088d64ef3706325643a422' ...
header.tmpl
header.tmpl 不能把 nonce 写死。关键是要取得 Gitea 当前请求生成的 nonce。
所以针对你现在的 Gitea 1.27.3,我更建议不要继续和动态 nonce 对抗,而是把 GTM JavaScript 改成外部 JS 文件,这样 header.tmpl 本身不再包含 inline JavaScript。
<!-- Google Tag Manager -->
<script src="{{AppSubUrl}}/assets/js/gtm-custom.js" defer></script>
<!-- End Google Tag Manager -->
Gitea 官方支持通过 custom 目录提供自己的静态资源。
然后创建:
mkdir -p /var/lib/docker/volumes/gitea_gitea-data/_data/gitea/public/assets/js
nano /var/lib/docker/volumes/gitea_gitea-data/_data/gitea/public/assets/js/gtm-custom.js
哪怕是这样,还是会出现 CSP 错误。
原因在于 GTM 的引用方式。
如果你要把 Matomo 用在当前 Gitea 上,建议和刚才 GTM 一样:不要把 Matomo 的初始化代码直接写成 inline <script>,否则还是会遇到 Gitea 的 CSP nonce 问题。
你当前 GTM 遇到的麻烦是 GTM 自己会进一步执行/生成各种 Tag,因此 CSP 会比较复杂。
Matomo 如果只是使用你上面这种标准 tracker:
src.sharkdat.com
│
├── /assets/js/matomo-custom.js
│
└── analytics.isharkfly.com/matomo.js
│
└── matomo.php
修改后的部署版本为:
var _paq = window._paq = window._paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u = 'https://analytics.isharkfly.com/';
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '1']);
var d = document;
var g = d.createElement('script');
var s = d.getElementsByTagName('script')[0];
g.async = true;
g.src = u + 'matomo.js';
// Copy Gitea's current CSP nonce to Matomo
var n = d.querySelector('[nonce]');
if (n) {
g.setAttribute(
'nonce',
n.nonce || n.getAttribute('nonce')
);
}
s.parentNode.insertBefore(g, s);
})();
Gitea 官方知道 Cloudflare 的页面/资源优化和改写功能可能破坏 Gitea;
但暂时没有证据表明 Gitea 官方已经把你现在这个 Cloudflare + GTM/Gitea JS initialization 问题作为同一个已知 Bug 明确记录。
这下面的问题主要是因为 CloudFlare 的脚本预加载, Gitea 的 CSP 安全机制会识别到错误干扰前端加载。




Comments