React Django 前后端分离开发实践

React Django 前后端分离开发实践

Web Application Development (17-637)的course project,采用了前后端分离的开发与部署,小白入门项目,非常基础。

技术栈

前端:React+Reactstrap+Semantic UI

后端:Django+Django REST framework

前后端交互:axios

项目介绍

项目是一个游戏购物网站,需要实现的功能主要有

  • 用户: login, logout, register
  • 商品: product, product rating, comment
  • 订单: shopping cart, checkout, view history order

跨域问题

前后端的交互使用axios,因为react和django在不同的端口,涉及跨域交互,采用的解决方案为cors。具体如下:

  1. 后端安装 django-cors-headers

  2. 后端配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'server' # 改成你对应的app名
    'corsheaders',
    ]

    MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware', # 注意顺序
    'django.middleware.common.CommonMiddleware', # 注意顺序
    # 'django.middleware.csrf.CsrfViewMiddleware', # 可能会有安全问题,但再说8
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ORIGIN_WHITELIST = ['*']

    CORS_ALLOW_METHODS = [
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
    ]

    CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-type'
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    ]
  3. 前端安装、使用axios

    见另外一篇推文

登陆态管理

最最基础,不在意任何安全性,一刷新就丢失登陆态的管理方式:将登陆态与登陆的用户作为react home/app component的props,登陆态将层层传递给子component。后端不做任何管理登陆态的处理。

进阶:cookie/localStorage保存登陆状态,从服务器获取token。接近ddl了没时间实现,具体可以参考链接1 链接2

功能实现

商品、购物车和订单的部分都比较基础,基本的react component和rest api就能够实现,不赘述。

部署

能力有限,部署也用了最简单的方式,前后端分别在两个server部署。前端以静态网站形式部署在EC2,后端也部署在EC2,都使用Apache HTTP Server.

  • 后端:EC2

    安装 Django

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sudo apt-get update

    sudo apt-get upgrade

    sudo apt-get install python3-pip

    sudo -H pip3 install --upgrade pip

    sudo -H pip3 install django

    sudo reboot

    安装Apache HTTP Server

    1
    2
    3
    sudo apt-get install apache2

    sudo apt-get install libapache2-mod-wsgi-py3

    开启80端口:EC2 Console-secruity group-Inbound-Edit-Add Rule-HTTP-Save

    git clone后端代码

    Apache Configuration

    1
    sudo <edit> /etc/apache2/apache2.conf
    • Comment out default mapping for “/“ url – it’s around line 159:

      1
      2
      3
      4
      5
      #<Directory />
      # Options FollowSymLinks
      # AllowOverride None
      # Require all denied
      #</Directory>
    • Insert alias for “/“ url:

      1
      2
      WSGIScriptAlias / /home/ubuntu/PROJECTNAME/APPNANE/wsgi.py
      WSGIPythonPath /home/ubuntu/PROJECTNAME
    • Add permissions for example project directory:

      1
      2
      3
      4
      5
      <Directory /home/ubuntu/PROJECTNAME>
      <Files wsgi.py>
      Require all granted
      </Files>
      </Directory>

    重启Apache

    1
    2
    3
    4
    cd ~
    sudo chgrp -R www-data PROEJCTNAME
    chmod -R g+w PROEJCTNAME
    sudo apache2ctl restart

    因为我们的后端只提供rest接口数据,所以不需要serve static files

  • 前端

    参考该链接

    1. 在前端运行num run build

    2. 和后端类似的步骤在EC2 instance安装Apache Server

    3. 将第一步build folder下所有的文件复制到/var/www/html文件夹中

    4. sudo /etc/httpd/conf/httpd.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<Directory "/var/www/html">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.4/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride All

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

#
# Controls who can get stuff from this server.
#
Require all granted
</Directory>

踩过的坑记录

axios get 和 post交互的区别

apache server 静态网站部署的路径

apache server 中 sudo -H pip3 install和pip install的区别

🥬🐔的第一个Web项目,有空要重新做下登陆态管理。