从外部正确访问 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
之类的东西(我这样做),那么您仍然无法获得正确的文件分辨率。
这个问题有什么好的解决办法吗?我正在考虑的选项:
- 将所有必要的 URL 引导到 Django 模板内的 JS 变量中
- 使用
data
标签将 url 存储在一些隐藏的 HTML 标记中(再次通过 django 模板)
- 创建一个 API 来获取 URL(这看起来很疯狂,并且在性能方面会很糟糕)。
只是想知道是否有解决此问题的标准做法或库?我 运行 多次遇到这个问题,但从未找到满意的解决方案。
我目前的解决方案(即使不是最优雅的,也能正常工作)只是在 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 必须异步。 (可能会破坏交易。)
- 软件工程师必须花费更多时间(昂贵)。
我有一个 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
之类的东西(我这样做),那么您仍然无法获得正确的文件分辨率。
这个问题有什么好的解决办法吗?我正在考虑的选项:
- 将所有必要的 URL 引导到 Django 模板内的 JS 变量中
- 使用
data
标签将 url 存储在一些隐藏的 HTML 标记中(再次通过 django 模板) - 创建一个 API 来获取 URL(这看起来很疯狂,并且在性能方面会很糟糕)。
只是想知道是否有解决此问题的标准做法或库?我 运行 多次遇到这个问题,但从未找到满意的解决方案。
我目前的解决方案(即使不是最优雅的,也能正常工作)只是在 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 必须异步。 (可能会破坏交易。)
- 软件工程师必须花费更多时间(昂贵)。