前言

现在替实验室做的项目,前端用的是React,后端是Python的Django,并且要前后端分离,前端通过向后端端口发送fetch请求调用后端api,数据通过json交换。因此需要用Nginx分别部署前端和后端。

前端

先在React项目文件下运行npm run bulid进行打包,然后上传至服务器。服务器安装完Nginx后就可以新建站点配置。

server
{
    listen 80;
    server_name www.xxxx.com;    # 网站域名
    index index.html;
    root /www/wwwroot/React;    # React项目的路径
    
    # url转发
    location /{
        try_files $uri $uri/ @router;
        index index.html;
    }
 
    location @router {
        rewrite ^.*$ /index.html last;
    }
}

因为React只有一个index.html,url需要都转发至index.html才能正常访问。比如在React中编写访问/login跳转到登录,但是如果不转发,访问时会找不到资源提示403。而转发后则能正常调用相应的js等从而正常访问。

重启一下Nginx服务,浏览器输入域名就可以访问了。

后端

后端相对麻烦一些,还额外需要安装uWSGI。大概思路是Nginx接收并处理静态请求,一旦收到动态请求,则转发给uWSGI,再由uWSGI交给Django进行处理。

另外这样前后端分离可能涉及到跨域,得安装django-cors-headers来解决Django的跨域问题,需要的话可以百度一下设置的教程。

先将Django项目打包上传至服务器。安装uWSGI以后,在Django项目路径下新建一个uwsgi.ini,然后进行配置。

[uwsgi]
socket=127.0.0.1:8001
chdir=/www/wwwroot/Django
module=Django.wsgi
workers=4

socket:定义项目运行的端口
chdir:项目路径
module:Django项目会自动包含一个wsgi.py,一般在路径下的同名文件夹中,例如.../Django/Django/wsgi.py。这里只要填写wsgi.py所在文件夹.wsgi即可。
workers:进程数
有需要的话,还有其他额外的配置参数,可以参考官方文档。

接着需要在Nginx中对uWSGI进行配置。

server
{
    listen 8000;         # 端口,前端请求往这发
    server_name api.xxxx.com;
    root /www/wwwroot/Django;   #项目路径
    location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8001;      # uWSGI中配置的项目端口
        uwsgi_param UWSGI_SCRIPT Django.wsgi; # 同前面的wsgi.py
        uwsgi_param UWSGI_CHDIR /www/wwwroot/Django/; #项目路径
    }
    location /static/ {
        alias /www/wwwroot/Django/static/; #静态资源路径
    }
}

这里Nginx监听了8000端口,从8000端口接收请求,而uWSGI中项目工作在8001端口,注意区分。

更新:其实可以让后端和前端共用一个域名,在路径上加上/api/作区分:

server
{
    listen 80;
    server_name www.xxxx.com;    # 网站域名
    index index.html;
    root /www/wwwroot/React;    # React项目的路径
    
    # 先前缀匹配/api/,如果匹配到说明是调用API的请求,转发到uwsgi
    location ^~ /api/
    {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8001;      # uWSGI中配置的项目端口
        uwsgi_param UWSGI_SCRIPT MAIN_backend.wsgi; # 同前面的wsgi.py
        uwsgi_param UWSGI_CHDIR /www/wwwroot/MAIN_backend/; #项目路径
    }

    # 否则就转发到前端
    location /{
        try_files $uri $uri/ @router;
        index index.html;
    }
 
    location @router {
        rewrite ^.*$ /index.html last;
    }
}

运行:

uwsgi --ini /www/wwwroot/Django/uwsgi.ini

Django项目就会被启动。

通过杀掉uWSGI中设定的项目端口:

fuser -k 8001/tcp

就可以停止Django项目的运行。

另外通过Supervisor,能够实现开机自启与进程保护。
配置可以参照:

[program:django_auto]
command=/usr/local/bin/uwsgi --ini /www/wwwroot/Django/uwsgi.ini
directory=/www/wwwroot/Django/
autorestart=true
startsecs=3
startretries=3
stdout_logfile=/www/server/panel/plugin/supervisor/log/django_auto.out.log
stderr_logfile=/www/server/panel/plugin/supervisor/log/django_auto.err.log
stdout_logfile_maxbytes=2MB
stderr_logfile_maxbytes=2MB
user=root
priority=1
numprocs=1
process_name=%(program_name)s_%(process_num)02d

重启Nginx,后端部分应该就可以正常工作了。

前端只需要发送请求到上面Nginx设置的后端域名处(没有域名就发到公网ip地址:8000),就可以实现调用。例如前端(这里仅包含请求的收发,不包括处理):

fetch('http://api.xxxx.com/login/',{
    method: "POST",
    body: JSON.stringify(values),
    headers: {
    'content-type': 'application/json'
    }
})

后端urls.py:

urlpatterns = [
    path('login/', views.login),
]

更新:如果按照上文更新处,让前后端共用域名,那么请求就改成

fetch('http://www.xxxx.com/api/login/',{
    method: "POST",
    body: JSON.stringify(values),
    headers: {
    'content-type': 'application/json'
    }
})

后端urls.py:

urlpatterns = [
    path('api/login/', views.login),
]
如果觉得我的文章对你有用,请随意赞赏