现象描述
前端通过Nginx访问pdf时在不同的浏览器、不同的环境上表现的不完全一样。偶然性特别大,有时候能正常加载pdf文件,有时候提示“未能加载PDF文档”,如图【未能加载pdf文档】所示。最关键的是不走Nginx,通过ip和端口号能正常加载pdf文档,一旦走了Nginx就出现上述所说那种不稳定的现象。
未能加载pdf文档.png
产生原因
在开发和正式环境采用Django自带的from django.views.static import serve
处理静态文件加载问题,如下述代码所示。
from django.conf.urls import include, url, patterns
from django.contrib import admin
from django.conf import settings
from django.views.static import serve
urlpatterns = patterns('',
# xxxx PDF路径 settings.ALERT_PDF_ROOT 是在settings.py中写的变量(pdf所在路径)
url(r'^my-report/(?P<path>.*)$', serve,
{'document_root': settings.ALERT_PDF_ROOT}),
)
在有Nginx的正式环境中是这样配置的Nginx,如下述代码所示。
location ~*\/my-report/ {
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_pass http://web.xxx.com:9010; #Django项目启动的端口号
proxy_set_header X-Real-IP $remote_addr;
}
原因分析
Django的django.views.static.serve
处理静态文件适合在开发环境,而正式部署时,Django不需要做任何事情,让Nginx来处理静态文件即可。
解决方案
先注释掉在Django的urls.py中用django.views.static.serve
处理静态文件那段代码,然后将Nginx的配置文件改成如下代码所示。
# xxx是pdf所在路径,举例:
# pdf所在路径为: /home/xxx/report/pdf/
# 那么xxx的值就应该为 /home/xxx/report/pdf/
location /my-report/ {
alias xxx;
}
知识扩展-1(未亲测,仅供参考)
若想在开发环境用django.views.static.serve
处理静态文件,在正式环境中用Nginx处理静态文件,且在正式环境中不想注释用django.views.static.serve
写的处理静态文件的代码的话,那么可以如下操作:
#在urls.py文件中最后加上以下代码----此方法未亲自验证,参考https://my.oschina.net/u/993130/blog/214841
# settings.ALERT_PDF_ROOT 是在settings.py中配置的pdf所在路径
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^my-report/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.ALERT_PDF_ROOT},name="my-report"),
)
在开发环境DEBUG = True,自然会走Django处理静态文件这一条路,而在正式环境中DEBUG = False,自然不会让Django处理静态文件
Nginx按处理静态文件来处理,就像上面写的解决方案那样处理静态文件即可。
知识扩展-2 (亲测了alias这种,另一种未亲测,仅供参考)
root目录与alias目录的区别(Nginx路径location配置中,使用root目录与alias目录的区别)
- alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的
- root指定的目录是location匹配访问的path目录的上一级目录,这个path目录一定要是真实存在root指定目录下的;
举例说明
比如静态资源文件在服务器/var/www/static/目录下
1)配置alias目录
location /static/ {
alias /var/www/static/;
}
注意:alias指定的目录后面必须要加上"/",即/var/www/static/不能改成/var/www/static
访问http://IP:PORT/static/index.html时,实际访问的是/var/www/static/index.html
2) 也可改成配置root目录
location /static/ {
root /var/www/;
}
注意:location中指定的/static/必须是在root指定的/var/www/目录中真实存在的
两者配置后的访问效果是一样的。
配置习惯
一般情况下,在nginx配置中的良好习惯是:
- 在location / 中配置root目录
- 在location /somepath/ 中配置alias虚拟目录
配置默认主页
比如访问 http://IP:PORT/,默认访问服务器/var/www/static/目录下的index.html
1)配置alias目录方式
location / {
alias /var/www/static/;
index index.html index.htm;
}
2)配置root目录方式
location / {
root /var/www/static/;
index index.html index.htm;
}
网友评论