如何部署连接到 Django RESTful API 的静态网站?

How to deploy static website connecting to Django RESTful API?

首先,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 的 hash/version 编号,将在下一个 minification/build 期间重新生成。我是否需要添加额外的逻辑来摆脱这些东西并将 grunt 的输出目录复制到 django 的静态和模板目录?

或者还有其他方法可以使这项工作,正确的方法,我错过了?

你的架构已经很干净了,不需要让 Django 知道 g运行t 或提供静态文件,也不需要使用 JS hacks 来猜测端口号

反向代理

使用 反向代理 像 nginx 或任何其他您喜欢的 Web 服务器作为静态文件 REST 的前端API.

In computer networks, a reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers. These resources are then returned to the client as though they originated from the proxy server itself. (Wikipedia)

我将概述重要方面,但不会过多介绍细节:

URL 用于 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 被映射到端口 8000 上的 /api 和 运行s(例如你可以 运行 gunicorn 在那个端口上,或者任何您喜欢的其他服务器)

http://nginx.org/en/docs/http/ngx_http_proxy_module.html

URL 用于我们的前端应用程序

接下来 nginx 将提供来自 g运行t 的静态文件,只需将其指向静态文件夹

location / { alias /app/static/; }

以上假定您的静态资源位于 /app/static/ 文件夹中(例如 index.html、您的 CSS、JS 等)。所以这主要是为了加载您的 BackboneJS 应用程序。

Django 静态文件

下一步不是必需的,但如果您有与 Django 应用程序一起使用的静态文件(使用 ./manage.py collectstatic 生成的静态文件,例如 Django 管理员或 Django 的 UI REST Framework 等),只需根据您的 Django settings.py STATIC_URLSTATIC_ROOT

进行映射
location /static { alias /app/django_static_root/; }

/staticdjango_static_root分别是STATIC_URLSTATIC_ROOT

总结

例如当你点击 example.com/ 时,nginx 只是提供静态文件,然后当 JS 脚本对 /api 进行 REST 调用时,它会被困在 /api nginx 位置并转发给 Django

最终结果是,example.com/example.com/api 都访问了同一个前端 Web 服务器,该服务器将它们代理到正确的位置

好了,保留代理解决了您的端口和子域问题(以及许多其他问题,例如来自 Django 的缓慢静态文件和 Web 浏览器和防火墙中的同源策略,除了默认的 HTTP 和 HTTPS 端口外不喜欢任何东西)