Vue3+TypeScript+Django Rest Framework 搭建个人博客(五):网站部署

本文详细讲述了如何完成博客开发并部署到公网服务器,涉及云服务器选购、操作系统设置、域名购买、SSL证书、备案、Python环境配置、Vue和TypeScript前端部署、后端Python与uwsgi部署、Nginx作为反向代理和负载均衡,以及数据库迁移至MySQL的过程。

博客网站开发完成后,最后一棒是将博客网站部署到公网服务器上,提供域名访问,能通过搜索引擎搜索到的博客网站才是真正的博客网站。

大家好,我是落霞孤鹜,经过几个星期的努力,我们已经完成了博客的开发。这一章我们开始开始部署博客网站,通过公网服务器和域名访问我们的博客网站。

一、准备工作

为了能实现我们的网站能通过域名访问,我们需要具备几个条件:

  1. 购买云服务器,这里可以自行选择购买阿里、腾讯、华为、百度,各个平台都有自己特定的优惠,选择合适自己的一个平台即可。
  2. 安装服务器的操作系统,作为服务器,一般采用linux系统,ubuntu,cent os,debian都可以
  3. 购买一个域名,可以通过云服务器提供商平台上的域名,.cn.com 都可以。
  4. 购买域名证书,只有具备了证书后,通过域名访问才会不被浏览器提示存在安全问题。
  5. 对网站进行备案,目前备案需要进行两次,一次是在工信部的平台进行 ICP 备案,通过这个备案后,还需要完成公安联网备案。

二、网站部署

在完成了准备工作后,正式开始我们的网站部署。

2.1 Python

由于我们的后端代码是Python编写的,所以在服务器上部署的时候,需要安装Python运行环境。

这里的安装方式,我采用官网的教程,版本是3.7。教程地址:https://docs.python.org/zh-cn/3.7/using/unix.html

安装完成后在命令行中运行如下命令验证是否安装成功

python -V
pip -V

2.2 代码发布

2.2.1 前端代码
2.2.1.1 编译

由于我们采用的是 Vue 和 TypeScript 编写的前端,因此在部署之前,需要编译成原生 Javascript 代码。

在前端代码根目录下,执行如下命令

yarn build

执行完成后,会在代码路径下生成 dist文件夹,里面是编译后的代码,文件结构如下图

2.2.1.2 上传

在服务器中,Home目录下,创建一个文件夹blog,在blog下创建文件夹frontend

cd ~
mkdir blog
cd blog
mkdir frontend

然后将本地dist文件夹下的前端文件通过FTP工具上传到~/blog/frontend路径下,前端代码发布完成。

2.2.2 后端代码

由于 Python 是脚本语言,所以代码本身不需要经过编译,直接将源代码上传到服务器对应路径即可。

2.2.2.1 依赖安装

Python 的运行服务器,我们采用 uwsgi,因此需要先在服务器上安装依赖,执行如下命令

pip install uwsgi

安装完成后,通过命令验证是否安装成功

uwsgi --version
2.2.2.2 编写 uwsgi配置文件

在后端代码项目路径下新建文件uwsgi.ini,我们通过socket的方式连接后端接口,配置信息如下:

[uwsgi]
socket = 127.0.0.1:8000
# 可以理解为此文件的绝对路径
chdir = ~/blog/backend/
# wsgi与chdir的相对路径
wsgi-file = project/wsgi.py
processes = 4
# 日志
daemonize = ~/blog/backend/logs/uwsgi.log
pidfile = ~/blog/backend/uwsgi.pid
master = True

在后端代码项目路径下新建文件uwsgi.param,文件内容如下

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
2.2.2.3 上传代码

在服务器的~/blog文件夹下,创建backend文件夹

cd ~/blog
mkdir backend

通过 FTP 工具将后端代码上传到~/blog/backend文件夹下,包括刚刚创建的uwsgi.ini文件然后在backend文件夹下,创建logs文件夹,用来记录日志

mkdir logs

至此,后端代码已经部署到位。

2.2.2.4 启动和停止后端服务

通过命令启动后端代码

uwsgi --ini ~/blog/backend/uwsgi.ini

测试可以通过日志文件查看启动后的服务器日志

tail -f ~/blog/backend/logs/uwsgi.log

停止命令如下:

uwsgi --stop ~/blog/backend/uwsgi.pid

后期如果后端代码更新,则需要先停止uwsgi服务后,再启动代码的更新。

2.3 Nginx

在当前的网站部署中,Nginx作为反向代理服务器部署网站是主流操作,也已经是成熟的网站部署方案。

Nginx在网站部署中, 一般会有以下几个作用:

  1. 反向代理,通过代理内网服务器,从而让外网的客户端访问到内网服务器提供的能力和数据。
  2. 负载均衡,分担后端服务器的压力
  3. HTTP服务器,Nginx本身也是一个静态资源的服务器,且在处理静态资源的请求和响应,比老牌的 Web 服务器更优秀,性能更好。通过 Nginx 实现动态和静态的分离部署。
2.3.1 安装

网上有很多教程,我这里提供一个参考教程 Linux下nginx的安装 - 浊酒尽 - 博客园 (cnblogs.com)

2.3.2 证书文件

在前面的准备工作中,有提到域名证书,此时将域名证书提供商平台上提供的证书文件下载下来,解压后,将 Nginx 的证书上传到服务器的 Nginx 安装路径中的conf文件下。

2.3.3 配置说明

Nginx 的配置文件一般存放在 Nginx 安装路径下的conf文件夹中,名称是 nginx.conf

2.3.3.1 静态文件代理

这里有两部分静态文件,一部分是前端代码文件,一部分是通过上传接口获得的媒体文件

location / {
   root ~/blog/frontend/dist;
   index index.html index.htm;
   if (!-e $request_filename) {
       rewrite ^/(.*) /index.html last;
       break;
   }
}
location /upload/ {
   root ~/blog/backend/;
   expires 24h;
}
2.3.3.2 后端接口代理

location里面有很关键的两行配置uwsgi_pass bloginclude ~/blog/backend/uwsgi.param,明确的是通过uwsgi的方式代理 Python 的接口

# server
    upstream blog{
       server 127.0.0.1:8000;
    }

location /api/ {
            uwsgi_pass blog;
            include ~/blog/backend/uwsgi.param;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header accept-encodeing 'gzip, deflate';
            proxy_set_header content-type 'application/json';
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header authorization $http_authorization;
            proxy_set_header accept '*/*';
            proxy_set_header x-bce-date $http_x_bce_date;
        }
2.3.3.3 静态文件Gzip压缩

配置Gzip压缩的原因是在前后端分离的场景下,网站首屏需要加载的内容很多,通过缩小网络传输过程中的文件大小,从而加快首屏渲染时的静态文件加载。

# Gzip
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 3;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    gzip_buffers 32 4k;
    gzip_http_version 1.0;
2.3.3.3 域名配置
 server {
       listen 80;
       server_name www.longair.cn;
       rewrite ^(.*)$ https://${server_name}$1 permanent;
    }

server {
        listen       443 ssl;
        server_name www.longair.cn;
        root html;
        index index.html index.htm;
}
2.3.3.3 Https证书文件配置
ssl_certificate      /etc/nginx/longair.cn_nginx/server.crt;
ssl_certificate_key  /etc/nginx/longair.cn_nginx/server.key;
ssl_session_timeout  5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
2.3.3.3 Http 自动转 Https

在访问 80 端口时,重定向到 433 端口中。

server {
       listen 80;
       server_name www.longair.cn;
       rewrite ^(.*)$ https://${server_name}$1 permanent;
    }
2.3.3.3 博客文章详情跳转404问题配置

由于我们使用 Vue 框架编写的前端代码,路由模式采用的是 history,这种模式的路由可读性强,但文章详情页面的路由如果通过新开页面的方式,会出现404的问题,因此我们需要对这种情况做处理,配置原理是,访问的路径如果不是文件结尾时,则自动重定向到首页,进入到index.html 后就可以通过路由变动进入到单页应用的路由,从而正确渲染详情页面。Vue-router 官网文档:HTML5 History 模式 | Vue Router (vuejs.org)

location / {
            root ~/blog/frontend/dist;
            index index.html index.htm;
            if (!-e $request_filename) {
                rewrite ^/(.*) /index.html last;
                break;
            }
        }
2.3.4 完整配置

完整配置如下:

user  root;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    keepalive_timeout  65;

    client_max_body_size 200M;

    # Gzip
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 3;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    gzip_buffers 32 4k;
    gzip_http_version 1.0;

    # server
    upstream blog{
       server 127.0.0.1:8000;
    }

    # blog http
    server {
       listen 80;
       server_name www.longair.cn;
       rewrite ^(.*)$ https://${server_name}$1 permanent;
    }

    server {
        listen *:80;
        listen *:443 ssl;
        listen [::]:80;
        listen [::]:443 ssl;
        server_name longair.cn;
        ssl_certificate      /etc/nginx/longair.cn_nginx/server.crt;
        ssl_certificate_key  /etc/nginx/longair.cn_nginx/server.key;
        return 301 https://www.longair.cn$request_uri;
    }

    # blog https
    server {
        listen       443 ssl;
        server_name www.longair.cn;
        root html;
        index index.html index.htm;

        ssl_certificate      /etc/nginx/longair.cn_nginx/server.crt;
        ssl_certificate_key  /etc/nginx/longair.cn_nginx/server.key;
        ssl_session_timeout  5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        location / {
            root ~/blog/frontend/dist;
            index index.html index.htm;
            if (!-e $request_filename) {
                rewrite ^/(.*) /index.html last;
                break;
            }
        }
        location /upload/ {
            root /blog/backend/;
            expires 24h;
        }
        location /api/ {
            uwsgi_pass blog;
            include ~/blog/backend/uwsgi.param;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header accept-encodeing 'gzip, deflate';
            proxy_set_header content-type 'application/json';
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header authorization $http_authorization;
            proxy_set_header accept '*/*';
            proxy_set_header x-bce-date $http_x_bce_date;
        }

        error_page 500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location = /50x.html {
            root ~/blog/frontend/dist;
        }
    }

}

三、网站的维护

3.1 Nginx的维护

3.1.1 启动命令
/usr/local/nginx/sbin/nginx -s start
3.1.2 停止命令
/usr/local/nginx/sbin/nginx -s stop
3.3.3 重启命令
/etc/nginx/sbin/nginx -s reload
3.3.4 日志查看命令
tail -f /etc/nginx/logs/access.log
tail -f /etc/nginx/logs/error.log

3.2 UWSGI的维护

3.2.1 启动命令
uwsgi --ini ~/blog/backend/uwsgi.ini
3.2.2 停止命令
uwsgi --stop ~/blog/backend/uwsgi.pid
3.3.3 日志查看命令
uwsgi --stop ~/blog/backend/uwsgi.pid

四、关于数据库

在开发阶段,我们采用的是非常方便的sqlite数据库,但是如果当网站部署到服务器上以后,再采用sqlite就会出现很多问题,比如数据安全问题,数据更新问题等,因此我们在博客部署上线时,需要切换成 Mysql 数据库。

4.1 Mysql 安装

我使用的5.7版本,安装操作,请依据自己的操作系统参考官网教程安装。MySQL :: MySQL 5.7 Reference Manual :: 2 Installing and Upgrading MySQL

4.2 数据库搭建

在服务器上,通过命令行完成数据库的搭建。

4.2.1 root登录
mysql -uroot -p

然后输入密码,回车,登录进入数据库。

4.2.2 创建数据库
  1. 创建数据库
create database blog character set utf8mb4;
  1. 创建用户
create user 'blog'@'%' identified by '12345678';
  1. 用户赋权
grant all privileges on blog.* to 'blog'@'%';
flush privileges;

4.3 后端配置调整

4.3.1 生产和开发环境隔离

在开发阶段,通过sqlite数据库,调试方便,访问速度快,而生产环境上,使用 Mysql 会更安全。所以我们希望开发和生产环境使用不同的数据库配置。

因此我们通过在系统中的环境变量来判断是生产环境还是测试环境,此种方式代码可以保持一套,部署时不用做任何调整。

同时需要调整允许访问的 host 信息。

4.3.2 数据库密码保护

由于我们的代码可能会通过代码仓库管理,如果是Github等仓库,可以会泄露自己的数据库密码,因此我们这里通过单独的配置文件来记录数据库账号信息,然后在Python中通过读取数据库账号配置文件来获取信息,从而实现数据库密码保护。

4.3.3 配置
4.3.3.1 project/settings.py
ALLOWED_HOSTS = ['www.longair.cn', '127.0.0.1', 'localhost', ]

ENV_PROFILE = os.getenv("PYTHON_ENV")

if ENV_PROFILE == "production":
    import configparser

    cf = configparser.ConfigParser()
    cf.read('/blog/db.cnf')  # 这个文件的内容在下一步会创建,至于路径是哪里都可以,只要下一步创建的文件是在这里写的路径下即可
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': cf.get('db', 'database'),
            'USER': cf.get('db', 'user'),  # 从配置文件中获取数据库用户名
            'PASSWORD': cf.get('db', 'password'),  # 从配置文件中获取数据库密码
            'HOST': 'localhost',
            'PORT': '3306'
        }
    }
    DEBUG = False  # 生产环境下关闭debug模式
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'data/db.sqlite3'),
        }
    }
    DEBUG = True
4.3.3.2 配置环境变量

通过修改环境变量管理文件,设置环境变量,输入命令vi ~/.bashrc,在里面添加一行:export PYTHON_ENV=production,然后按 esc,输入::wq 保存

最后输入source ~/.bashrc

4.3.3.3 增加数据库账号配置文件

~/blog下新增文件vi db.cnf,然后增加如下内容:

[db]
database = blog
user = blog
password = 12345678
default-character-set = utf8

数据库、账号、密码和上面的数据库信息保持一致。

恭喜你,至此,博客网站部署完成,可以通过域名来访问你的博客网站了。

下一篇我将总结一下在整个博客开发过程中遇到的问题和解决方案。

<think>我们正在使用Vue3 + TypeScript + Vite作为前端,Django作为后端(提供API接口)。需要配置前端项目以正确访问Django后端接口。 主要步骤: 1. 配置前端开发服务器代理(解决跨域问题) 2. 在Vue组件中发起API请求 3. 配置Django允许跨域(可选,如果前端代理配置成功则不需要) 详细步骤: ### 1. 配置Vite代理(解决开发环境跨域问题) 在`vite.config.ts`中配置代理,将特定前缀的请求转发到Django后端。 假设Django后端运行在`http://127.0.0.1:8000`(或`http://localhost:8000`),前端运行在`http://localhost:3000`。 修改`vite.config.ts`: ```typescript import { defineConfig } from &#39;vite&#39; import vue from &#39;@vitejs/plugin-vue&#39; export default defineConfig({ plugins: [vue()], server: { port: 3000, // 前端端口 proxy: { // 代理所有以/api开头的请求 &#39;/api&#39;: { target: &#39;http://127.0.0.1:8000&#39;, // Django后端地址 changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, &#39;&#39;) // 重写路径,去掉/api前缀(可选) } } } }) ``` 解释: - 当你在前端代码中请求`/api/some/path`时,Vite开发服务器会将其代理到`http://127.0.0.1:8000/some/path`(因为rewrite去掉了/api)。 - 如果你不想去掉前缀,可以去掉rewrite,那么请求`/api/some/path`会被代理到`http://127.0.0.1:8000/api/some/path`。 ### 2. 在Vue组件中发起请求 我们可以使用`axios`或`fetch`来发送请求。这里以axios为例。 安装axios: ```bash npm install axios ``` 在组件中使用: ```typescript <script setup lang="ts"> import { ref } from &#39;vue&#39; import axios from &#39;axios&#39; const users = ref([]) // 发起请求 axios.get(&#39;/api/user/&#39;) // 注意:这里使用了代理的前缀/api .then(response => { users.value = response.data }) .catch(error => { console.error(&#39;Error fetching users:&#39;, error) }) </script> ``` 如果Django的接口返回数据格式如引用[3]所示,那么你可以直接使用`response.data`获取数据。 ### 3. 配置Django允许跨域(生产环境部署时可能需要) 在开发环境中,我们通过Vite代理解决了跨域问题。但在生产环境中,前端静态文件通常由Nginx等服务器提供,此时需要配置后端允许跨域或通过Nginx代理。 如果前后端部署在同一个域名下,则不存在跨域问题。如果分开部署,可以在Django中安装`django-cors-headers`来允许跨域。 安装: ```bash pip install django-cors-headers ``` 在`settings.py`中配置: ```python INSTALLED_APPS = [ # ... &#39;corsheaders&#39;, # ... ] MIDDLEWARE = [ # ... &#39;corsheaders.middleware.CorsMiddleware&#39;, # 尽量放在最前面 # ... ] # 允许所有来源的跨域请求(开发时可设置,生产环境应指定具体域名) CORS_ALLOW_ALL_ORIGINS = True ``` ### 4. 生产环境配置 生产环境中,前端打包后需要将静态文件部署到Web服务器(如Nginx),并配置Nginx代理前端请求到Django后端。 一个简单的Nginx配置示例: ``` server { listen 80; server_name yourdomain.com; location / { root /path/to/your/vite/dist; # 前端打包后的dist目录 try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8000; # 将/api开头的请求转发给Django proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` ### 5. 处理Django静态文件(可选) 如果Django还需要提供自己的静态文件(如管理后台),则需要配置静态文件服务,但前后端分离架构下,通常前端静态文件由Nginx直接提供,Django只提供API。 ### 总结 1. 开发环境:通过Vite代理解决跨域问题。 2. 生产环境:通过Nginx代理API请求到Django,同时提供前端静态文件。 这样,前端在开发和生产环境中都能正确访问Django后端接口。 注意:在Django中,你可能已经配置了API的URL,例如: ```python # urls.py from django.urls import path from . import views urlpatterns = [ path(&#39;user/&#39;, views.UserList.as_view()), # 示例接口 ] ``` 因此,前端请求的路径需要与Django的路由匹配。 参考引用[3]中的接口返回数据,我们可以知道Django的API路径为`/user/`(注意末尾斜杠),所以前端请求的路径应为`/api/user/`(开发环境)或`/api/user/`(生产环境,由Nginx转发)。 在代码中,我们可以根据环境变量切换基础URL,但通常我们使用代理或Nginx统一前缀,这样前端代码中只需写相对路径。 例如,在axios中,我们可以创建一个实例并设置基础URL(可选): ```typescript // 创建一个axios实例 const api = axios.create({ baseURL: import.meta.env.DEV ? &#39;/api&#39; : &#39;https://yourdomain.com/api&#39;, // 开发环境使用代理,生产环境使用真实URL timeout: 5000 }) // 使用实例 api.get(&#39;/user/&#39;).then(...) ``` 在Vite中,环境变量以`import.meta.env`开头。我们可以在项目根目录下创建`.env`文件来定义环境变量,例如: ``` VITE_API_BASE_URL=/api ``` 然后在代码中: ```typescript baseURL: import.meta.env.VITE_API_BASE_URL ``` 这样,我们可以通过不同的环境文件(如`.env.production`)来覆盖这个值。 以上就是一个完整的配置实例。 引用说明: [^1] 提到了DjangoVue3的技术栈,但未涉及具体配置。 [^2] 提供了前端构建脚本的示例,其中使用了`vue-tsc`进行类型检查。 [^3] 展示了Django的一个API响应示例,并提到通过Vite初始化Vue项目。 因此,我们主要参考了这些技术栈的常见配置方式,并结合Vite的代理配置来解决接口访问问题。 相关问题: 1. 如何配置Vite开发服务器的HTTPS支持? 2. 如何在Vue 3项目中设置环境变量? 3. Vite的代理配置(proxy)如何解决跨域问题? 4. 如何优化Vite在TypeScript项目中的构建速度?</think>下面我将详细说明如何配置 Django 后端与 Vue 3 + TypeScript + Vite 前端之间的接口请求访问,包含完整配置步骤和代码示例: ### 完整配置方案 #### 1. 后端配置 (Django) **步骤 1: 安装依赖** ```bash pip install django djangorestframework django-cors-headers ``` **步骤 2: 配置 settings.py** ```python # settings.py INSTALLED_APPS = [ # ... &#39;rest_framework&#39;, &#39;corsheaders&#39;, ] MIDDLEWARE = [ &#39;corsheaders.middleware.CorsMiddleware&#39;, # 放在最前面 # ... ] # 允许所有来源的跨域请求(开发环境) CORS_ALLOW_ALL_ORIGINS = True # 或指定允许的源(生产环境) # CORS_ALLOWED_ORIGINS = [ # "http://localhost:3000", # "http://127.0.0.1:3000" # ] # 允许的请求方法 CORS_ALLOW_METHODS = [ &#39;GET&#39;, &#39;POST&#39;, &#39;PUT&#39;, &#39;PATCH&#39;, &#39;DELETE&#39;, &#39;OPTIONS&#39; ] # 配置API路由 ROOT_URLCONF = &#39;your_project.urls&#39; ``` **步骤 3: 创建 API 视图** ```python # api/views.py from rest_framework.decorators import api_view from rest_framework.response import Response @api_view([&#39;GET&#39;]) def user_list(request): users = [ {"id": 1, "name": "张三"}, {"id": 2, "name": "李四"} ] return Response(users) ``` **步骤 4: 配置路由** ```python # urls.py from django.urls import path from .api.views import user_list urlpatterns = [ path(&#39;api/users/&#39;, user_list, name=&#39;user-list&#39;), ] ``` #### 2. 前端配置 (Vue 3 + Vite) **步骤 1: 安装 Axios** ```bash npm install axios ``` **步骤 2: 配置 Vite 代理** ```typescript // vite.config.ts import { defineConfig } from &#39;vite&#39; import vue from &#39;@vitejs/plugin-vue&#39; export default defineConfig({ plugins: [vue()], server: { proxy: { &#39;/api&#39;: { target: &#39;http://127.0.0.1:8000&#39;, // Django 后端地址 changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, &#39;&#39;) } } } }) ``` **步骤 3: 创建 API 服务** ```typescript // src/services/api.ts import axios from &#39;axios&#39; const api = axios.create({ baseURL: import.meta.env.DEV ? &#39;/api&#39; : &#39;https://your-production-domain.com/api&#39;, timeout: 5000, headers: { &#39;Content-Type&#39;: &#39;application/json&#39;, &#39;X-Requested-With&#39;: &#39;XMLHttpRequest&#39; } }) // 添加请求拦截器 api.interceptors.request.use(config => { // 可在此处添加token等认证信息 return config }) // 添加响应拦截器 api.interceptors.response.use( response => response.data, error => { console.error(&#39;API Error:&#39;, error.response?.data || error.message) return Promise.reject(error) } ) export const getUsers = () => api.get(&#39;/users/&#39;) export const createUser = (userData: any) => api.post(&#39;/users/&#39;, userData) ``` **步骤 4:Vue 组件中使用 API** ```vue <!-- src/components/UserList.vue --> <script setup lang="ts"> import { ref, onMounted } from &#39;vue&#39; import { getUsers } from &#39;@/services/api&#39; interface User { id: number name: string } const users = ref<User[]>([]) const loading = ref(false) const error = ref<string | null>(null) const fetchUsers = async () => { try { loading.value = true const response = await getUsers() users.value = response } catch (err) { error.value = &#39;加载用户数据失败&#39; console.error(err) } finally { loading.value = false } } onMounted(() => { fetchUsers() }) </script> <template> <div> <h2>用户列表</h2> <div v-if="loading">加载中...</div> <div v-else-if="error" class="error">{{ error }}</div> <ul v-else> <li v-for="user in users" :key="user.id"> {{ user.name }} </li> </ul> </div> </template> ``` #### 3. 启动项目 1. 启动 Django 后端: ```bash python manage.py runserver 8000 ``` 2. 启动 Vue 前端: ```bash npm run dev ``` 访问 `http://localhost:3000` 即可看到前端获取并显示来自 Django 的用户数据 ### 关键配置说明 1. **跨域处理**: - 开发环境:通过 Vite 代理解决 (配置在 `vite.config.ts`) - 生产环境:通过 Django 的 CORS 配置或 Nginx 反向代理解决 2. **环境变量**: ```env # .env.development VITE_API_BASE_URL=/api # .env.production VITE_API_BASE_URL=https://your-api-domain.com/api ``` 3. **接口路径映射**: - 前端请求:`/api/users/` → Vite 代理 → Django 实际路径:`/users/` ### 常见问题解决 1. **跨域问题 (CORS)**: - 确保 `django-cors-headers` 已正确安装和配置 - 检查中间件顺序:`CorsMiddleware` 应放在最前面 2. **代理不生效**: - 确认 Vite 配置中的端口与 Django 端口一致 - 重启 Vite 开发服务器 3. **生产环境部署**: ```nginx # Nginx 配置示例 location /api { proxy_pass http://django-backend:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } ``` ### 完整项目结构 ``` project/ ├── backend/ # Django 项目 │ ├── api/ │ │ ├── views.py │ │ └── urls.py │ ├── settings.py │ └── manage.py │ └── frontend/ # Vue 项目 ├── src/ │ ├── services/ │ │ └── api.ts │ ├── components/ │ │ └── UserList.vue │ └── main.ts ├── vite.config.ts └── package.json ``` 这个配置方案实现了: 1. Vue 3 + Vite 前端通过代理无缝访问 Django API 2. TypeScript 类型安全的 API 调用 3. 开发环境与生产环境的路径自动切换 4. 完善的错误处理和加载状态管理 参考配置原理来自 Django REST Framework 的接口设计[^1] 和 Vite 的代理机制[^2],结合了实际项目中的最佳实践[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值