从外部正确访问 django 静态文件 javascript

Correctly accessing django static files from external javascript

我有一个 Django 应用程序使用 AngularJS 和一堆 JavaScript 和模板文件。

在我的 django 模板中,我可以使用 {% static %} 标签来正确引用这些文件,如下所示:

<script src="{% static "angular/myapp.app.js" %}"></script>

但是,外部文件本身显然 因此这不是一个选项。所以人们最常做的就是在那里硬编码静态路径:

$routeProvider.when('/', {
   // this works but is not ideal
   templateUrl: '/static/pages/some-angular-template.html',  
})

我看到了将 STATIC_URL 加载到 javascript 某处并使用它来构建引用的建议。像这样:

Django 模板:

var STATIC_URL = {{ STATIC_URL }};
function getStaticUrl(templatePath) {
  return STATIC_URL + templatePath;
}

外部 JS:

$routeProvider.when('/', {
   templateUrl: getStaticUrl('/pages/some-angular-template.html'),
})

这有点好,但仍然不完美,因为它只处理基本路径。如果您想使用 ManifestStaticFilesStorage 之类的东西(我这样做),那么您仍然无法获得正确的文件分辨率。

这个问题有什么好的解决办法吗?我正在考虑的选项:

只是想知道是否有解决此问题的标准做法或库?我 运行 多次遇到这个问题,但从未找到满意的解决方案。

我目前的解决方案(即使不是最优雅的,也能正常工作)只是在 django 模板中创建一个巨大的全局常量字典,然后直接在 JS 中引用它们。

Django 模板:

<script type="text/javascript">
    NG_STATIC_FILES = {
       "HOME": "{% static '/pages/home.html' %}",
       "SOMETHING_ELSE": "{% static '/pages/some-angular-template.html' %}",
    };
</script>

外部 JS:

$routeProvider.when('/', {
    templateUrl: NG_STATIC_FILES.SOMETHING_ELSE,
})

等等

其他选项1

使用你的 getStaticUrl 函数,但让它也附加一个查询字符串,如 ?v=abc,其中 abc 对于你的应用程序的每个部署版本都是唯一的,以破坏缓存。 (例如,您的 html 定义 window.ASSET_VERSION = 'abc',当您部署新版本的应用程序时,您的 html 定义 window.ASSET_VERSION = 'xyz'。)

优点:

  • 不需要庞大的全局字典。
    • 不需要维护
    • 在一个地方(如果重要的话)正在寻找您的应用的用户(包括恶意用户)可以看到有关您的应用的较少信息。 可能会节省服务器成本。

缺点:

  • 在部署新版本的应用程序期间,当用户访问该站点时,他们的浏览器将收到新的静态资产和旧的 html,不匹配可能会导致用户遇到错误。
  • 如果您使用 CDN,例如 CloudFront,则必须将其配置为在缓存键中包含查询字符串。
  • 可能使 A/B 无法进行测试?
  • 部署新版本的应用时,必须在部署新的html服务器之前上传新的静态资源,否则旧的静态资源将被您的部分用户长期错误使用时间。 (如果用户在部署期间访问您的站点,他们的浏览器将接收新的 html 和旧的静态资产,将使用新的查询字符串缓存这些旧资产,并继续使用这些旧资产,直到用户手动清除缓存、缓存的响应过期或下一次部署发生。)

其他选项2

类似于“创建 API 以获取 URLs”:将包含 URLs 的字典放入静态 json 文件中,并使您的 getStaticUrl 函数 return 获取 json 文件后解析为请求的 url 的 Promise。将版本 ID 放入 json 文件名或缓存清除查询字符串(见上文)中,以便可以缓存 json 文件。

优点:

  • 性能可能更好,因为 URL 数据缓存在浏览器中。
  • 可能会节省服务器成本。

缺点:

  • 所有想要这些 URL 之一的 JavaScript 必须异步。 (可能会破坏交易。)
    • 软件工程师必须花费更多时间(昂贵)。