現(xiàn)象描述
前端通過Nginx訪問pdf時(shí)在不同的瀏覽器、不同的環(huán)境上表現(xiàn)的不完全一樣。偶然性特別大,有時(shí)候能正常加載pdf文件,有時(shí)候提示“未能加載PDF文檔”,如圖【未能加載pdf文檔】所示。最關(guān)鍵的是不走Nginx,通過ip和端口號能正常加載pdf文檔,一旦走了Nginx就出現(xiàn)上述所說那種不穩(wěn)定的現(xiàn)象。

產(chǎn)生原因
在開發(fā)和正式環(huán)境采用Django自帶的from django.views.static import serve處理靜態(tài)文件加載問題,如下述代碼所示。
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的正式環(huán)境中是這樣配置的Nginx,如下述代碼所示。
location ~*\/my-report/ {
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_pass http://web.xxx.com:9010; #Django項(xiàng)目啟動的端口號
proxy_set_header X-Real-IP $remote_addr;
}
原因分析
Django的django.views.static.serve處理靜態(tài)文件適合在開發(fā)環(huán)境,而正式部署時(shí),Django不需要做任何事情,讓Nginx來處理靜態(tài)文件即可。
解決方案
先注釋掉在Django的urls.py中用django.views.static.serve處理靜態(tài)文件那段代碼,然后將Nginx的配置文件改成如下代碼所示。
# xxx是pdf所在路徑,舉例:
# pdf所在路徑為: /home/xxx/report/pdf/
# 那么xxx的值就應(yīng)該為 /home/xxx/report/pdf/
location /my-report/ {
alias xxx;
}
知識擴(kuò)展-1(未親測,僅供參考)
若想在開發(fā)環(huán)境用django.views.static.serve處理靜態(tài)文件,在正式環(huán)境中用Nginx處理靜態(tài)文件,且在正式環(huán)境中不想注釋用django.views.static.serve寫的處理靜態(tài)文件的代碼的話,那么可以如下操作:
#在urls.py文件中最后加上以下代碼----此方法未親自驗(yàn)證,參考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"),
)
在開發(fā)環(huán)境DEBUG = True,自然會走Django處理靜態(tài)文件這一條路,而在正式環(huán)境中DEBUG = False,自然不會讓Django處理靜態(tài)文件
Nginx按處理靜態(tài)文件來處理,就像上面寫的解決方案那樣處理靜態(tài)文件即可。
知識擴(kuò)展-2 (親測了alias這種,另一種未親測,僅供參考)
root目錄與alias目錄的區(qū)別(Nginx路徑location配置中,使用root目錄與alias目錄的區(qū)別)
- alias指定的目錄是準(zhǔn)確的,即location匹配訪問的path目錄下的文件直接是在alias目錄下查找的
- root指定的目錄是location匹配訪問的path目錄的上一級目錄,這個(gè)path目錄一定要是真實(shí)存在root指定目錄下的;
舉例說明
比如靜態(tài)資源文件在服務(wù)器/var/www/static/目錄下
1)配置alias目錄
location /static/ {
alias /var/www/static/;
}
注意:alias指定的目錄后面必須要加上"/",即/var/www/static/不能改成/var/www/static
訪問http://IP:PORT/static/index.html時(shí),實(shí)際訪問的是/var/www/static/index.html
2) 也可改成配置root目錄
location /static/ {
root /var/www/;
}
注意:location中指定的/static/必須是在root指定的/var/www/目錄中真實(shí)存在的
兩者配置后的訪問效果是一樣的。
配置習(xí)慣
一般情況下,在nginx配置中的良好習(xí)慣是:
- 在location / 中配置root目錄
- 在location /somepath/ 中配置alias虛擬目錄
配置默認(rèn)主頁
比如訪問 http://IP:PORT/,默認(rèn)訪問服務(wù)器/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;
}