Nextcloud 前端页面插入 JS 代码以使用 Google Analytics 分析

作为长期手搓 JS 的后端,对前端的安全规则几乎是一点都不熟悉,Java Spring 都是 Security 一把梭,这次给 PHP 语言编写的 Nextcloud 添加几行代码真的是要了我的老命了,赶紧记录一下别后面忘了再来一遍……
注:我是在虚拟主机上直接运行官方的 setup-nextcloud.php 安装,如果是服务器上下载安装应该目录类似,请自行查找文件。


首先需要明确的是 Nextcloud 使用了严格的 CSP (Content Security Policy) 配置,如果你想从外部引用任何 CSS 或者 JS 都应该第一时间去做对该来源信任的配置,本文就以添加 Google Analytics 的 Script 元素为例。

1、从 Google Analytics 官网获取站点的统计代码
获取 Google Analytics 代码 样例如下:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-xxxxxxxxxx"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-xxxxxxxxxx');
</script>

2、修改 Nextcloud 的 CSP 配置
配置文件路径:

站点根目录/lib/public/AppFramework/Http/ContentSecurityPolicy.php

添加以下几行,功能包括:① 允许执行页面内嵌的标签和事件监听函数;② 信任 Google 脚本和连接源。
添加信任源

3、添加 Google Analytics 代码到网站头
头生成 PHP 文件路径:

站点根目录/lib/private/legacy/template/functions.php

找到头生成方法,并添加方法:

/**
 * Global site tag (gtag.js) - Google Analytics
 */
function emit_google_analytics_script() {
	$g_a_s_01 = '<script nonce="' . \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() . '" defer src="https://www.googletagmanager.com/gtag/js?id=G-xxxxxxxxxx"></script>';
	$g_a_s_02 = '<script nonce="' . \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() . '" defer>window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}gtag("js", new Date());gtag("config", "G-xxxxxxxxxx");</script>';
	print_unescaped($g_a_s_01."\n");
	print_unescaped($g_a_s_02."\n");
}

之后在 emit_script_loading_tags() 方法中调用添加 Google Analytics 的代码:

/**
 * Print all <script> tags for loading JS
 * @param array $obj all the script information from template
 */
function emit_script_loading_tags($obj) {
	...
	emit_google_analytics_script();
	...
}

完成后刷新页面,就能去 Google Analytics 看到访问了,结束。