如何设置 nginx 以正确地为 React 和 Django 提供服务

Posted

技术标签:

【中文标题】如何设置 nginx 以正确地为 React 和 Django 提供服务【英文标题】:How to set nginx to serve React and Django properly 【发布时间】:2020-08-15 19:29:35 【问题描述】:

我使用 Linux 服务器将 React 应用程序作为前端,将 Django 作为后端。

gunicorn 配置如下:

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=name
Group=www-data
WorkingDirectory=/var/www/backend/app
ExecStart=/var/www/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/name/backend.sock app.wsgi:application

[Install]
WantedBy=multi-user.target

nginx的配置如下:

server 
    listen 80;
    root /var/www/frontend/build;
    server_name example.com;

    location = /favicon.ico  access_log off; log_not_found off; 

    location / 

    

    location /graphql 
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
        proxy_pass http://unix:/home/name/backend.sock;
    

Django 应用 urls.py 如下:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('reports/', include('reports.urls')),
    path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True)))
]

如果我向www.example.com/graphql 发出提取请求,它可以正常工作。

但如果我想按如下方式访问 Django 管理仪表板 www.example.com/admin/ 它不起作用。

如果我理解得很好,location /graphql 表示 Django 应用程序在该 url 上运行。因此,如果我想访问 urls.py 文件中的一些 url,我使用www.example.com/graphql/url from urls.py

不应该是www.example.com/graphql/graphql

如何访问管理仪表板?有什么不懂的好?

【问题讨论】:

【参考方案1】:

方法一

将您的 urls.py 更改为:

from django.urls import include, path
# ... other imports ...

sub_patterns = [
    path('admin/', admin.site.urls),
    path('reports/', include('reports.urls')),
    path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True)))
]

urlpatterns = [
    path('graphql/', include(sub_patterns)),
]

然后您将能够访问www.example.com/graphql/admin/ 的管理页面。

方法二

如果我理解得很好, location /graphql 表示 Django 应用程序在该 url 上运行。

实际上,没有。我们以一个虚构的 URL 为例:www.example.com/graphql/a/b/c/。 Django URL 调度程序将看到/graphql/a/b/c/(而不仅仅是您所期望的/a/b/c/)。

所以要让 Django 看到 /a/b/c/(同时仍然通过反转到 /graphql/a/b/c/ 来确保 reverse() 仍能正常工作),您可以编辑您的 nginx 配置:

// ...
    location /graphql 
        // ...
        // Add this line:
        proxy_set_header SCRIPT_NAME /graphql;
        // ...
    
// ...

注意:我从来没有在生产中使用过这种方法,可能会有一些并发症,所以我建议你做进一步的研究。

【讨论】:

location / 上提供 React 前端,location /graphql 上应该提供 Django 应用程序。 @Boky 好的。我现在知道了。编辑了我的答案。也许您应该在问题中明确指出 location / 块实际上并不是空白的。 @Boky 编辑了答案以向您展示不同的方法。

以上是关于如何设置 nginx 以正确地为 React 和 Django 提供服务的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual Studio 代码中配置设置,以便更漂亮地为 react.js 工作

如何正确地为隐藏在 UITableViewCell 中的 UIStackView 设置动画?

无法在 React 路由器中正确地为路径添加前缀

如何最好地为 UITableViewCell 或 UIButton 设置动画以重复亮起红色

如何正确地为 scss 进行嵌套导入?语义 UI 问题?

UICollectionView deleteItemsAtIndexPaths 不能正确地为补充视图设置动画