django部署问题一

时间:2023-02-09 15:59:27

django在GET请求时,如果URL结尾没有/django将返回301即自动加上/。django APPEND_SLASH参数默认为False。

nginx部署

一般Django部署使用nginx和uwsgi部署。nginx配置

upstream  django {
  	# 此处时docker部署中的容器名称。非docker部署直接使用ip+端口或者域名
    server dj-uwsgi:8000;
}

server {
    # 配置gzip
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 4;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types application/octet-stream model/gltf-binary text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    listen 80;
    server_name 127.0.0.1;
    root /usr/share/nginx/html/dist;
    if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$ ) {
        return 403;
    }
    index index.html index.htm;

    # 前端页面转发
    location / {
        try_files $uri /index.html;
    }

    location /api {
        # 路径重写 路径返回api之后的所有
        rewrite "^/api/(.*)$" /$1 break;
        include /etc/nginx/uwsgi_params;
        uwsgi_pass django;
    }
}

nginx location

语法规则: location [=|~|~*|^~] /uri/ { … }

  • = 开头表示精确匹配
  • ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。以xx开头
  • ~ 开头表示区分大小写的正则匹配 以xx结尾
  • ~* 开头表示不区分大小写的正则匹配 以xx结尾
  • !~!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
  • / 通用匹配,任何请求都会匹配到。

多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考)

首先精确匹配 = ->其次以xx开头匹配^~ -> 然后是按文件中顺序的正则匹配->最后是交给 / 通用匹配。

当有匹配成功时候,停止匹配,按当前匹配规则处理请求

nginx rewrite

last – 基本上都用这个Flag。 break – 中止Rewirte,不在继续匹配 redirect – 返回临时重定向的HTTP状态302 permanent – 返回永久重定向的HTTP状态301

rewrite "^/api/(.*)$" /$1 break;

  • "^/api/(.*)$" 匹配路径的正则表达式 把/api/以后的所有部分当做1组
  • /$1 重写的目标路径,这里用$1引用前面正则表达式匹配到的分组(组编号从1开始,也就是api),即/api/后面的所有。这样新的路径就是除去/api/以外的所有,就达到了去除/api前缀的目的

问题

django和nginx

假如发生如下请求

http://127.0.0.1/api/test

你需要得到如下请求

http://127.0.0.1/api/test ->301
http://127.0.0.1/api/test -> 200

真实请求

http://127.0.0.1/api/test ->301
# django redirect发挥作用。将导致错误
http://127.0.0.1/test/ -> 200