首先,google或SO搜索对我没有帮助:关于django静态文件的很多提示,我认为这些提示与此无关。
我继承了一个由以下项目组成的项目:
我的问题是:前端需要知道swampdragon和django服务器的地址;现在这些值是硬编码的,所以例如Backbone模型有如下行:
url: function() {
return App.BACKEND_URL+'settings/map';
}
为什么硬编码:后端可以在任何端口上提供或者有自己的子域;前端是静态的,通常会简单地抛入/ var / www(对于Apache)或使用一些非常简单的nginx配置。两者都将在同一个地方提供,但无法保证端口号或子域匹配。
创意编号1:尝试通过获取window.location.host并附加标准端口来猜测来自javascript的BACKEND_URL是什么。这很容易出错并容易出错。
创意编号2:将前端移动到Django并让它询问swampdragon凭据(它们将在主视图的上下文中发送)。问题是,前端文件是由grunt编译的。所以Django会期待像:
<script src="{% static 'scripts/vendor/modernizr.js' %}"></script>
我实际上已经
了<script src="scripts/vendor/a8bcb0b6.modernizr.js"></script>
其中'a8bcb0b6'是grunt的哈希/版本号,并将在下一次缩小/构建期间重新生成。我是否需要添加额外的逻辑来摆脱这些东西并将grunt的输出目录复制到django的静态和模板dirs?
还是有另一种方法可以使这项工作,正确的,我不知道了吗?
答案 0 :(得分:1)
您的架构已经很干净,不需要让Django了解grunt或提供静态文件,也不需要使用JS hacks来猜测端口号
使用反向代理(如nginx)或任何其他您喜欢的Web服务器作为静态文件和 REST API的前端。
在计算机网络中,反向代理是一种代理服务器 代表客户端从一个或多个服务器检索资源。 然后将这些资源返回给客户端,就好像它们一样 源自代理服务器本身。 (维基百科)
我将概述重要方面,而不是过多详细说明:
我们进行配置,以便nginx将API请求转发给Django
location /api {
proxy_pass http://127.0.0.1:8000; # assumes Django listens here
proxy_set_header Host $http_host; # preserve host info
}
所以上面假设您的Django REST映射到/api
并在端口8000
上运行(例如,您可以在该端口上运行gunicorn,或者您喜欢的任何其他服务器)
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
接下来nginx将通过简单地将其指向静态文件夹来提供来自grunt的静态文件
location / { alias /app/static/; }
以上假设您的静态资源位于/app/static/
文件夹中(如index.html
,您的CSS,JS等)。所以这主要是加载你的BackboneJS应用程序。
下一步不是必需的,但是如果您有与Django应用程序一起使用的静态文件(使用./manage.py collectstatic
生成的静态文件,例如django管理员或Django REST Framework的UI等),根据您的Django settings.py
STATIC_URL
和STATIC_ROOT
location /static { alias /app/django_static_root/; }
/static
和django_static_root
分别是STATIC_URL
和STATIC_ROOT
所以,例如当你点击example.com/
时,nginx只提供静态文件,然后当一个JS脚本对/api
进行REST调用时,它会被困在/api
nginx位置并被转发到Django < / p>
最终结果是,example.com/
和example.com/api
都点击了相同的前端Web服务器,将它们代理到正确的位置
所以你有它,保留代理解决了你的端口和子域问题(以及许多其他问题,比如来自Django的慢速静态文件和web浏览器和防火墙中的同源策略,除了默认的HTTP和HTTPS端口之外不喜欢任何东西)