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