前言
现在替实验室做的项目,前端用的是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),
]