当省略尾部斜杠时,静态文件不会加载到 Bottle 应用程序中
题
我正在使用 Bottle 通过 apache 提供测试文件。
以下是我的 apache 配置:
WSGIDaemonProcess temp user=www-data group=www-data processes=1 threads=5
WSGIScriptAlias /temp /opt/gridops/usage/temp/adapter.wsgi
<Directory /opt/gridops/usage/temp>
WSGIProcessGroup temp
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
adapter.wsgi
:
import os,sys
os.chdir(os.path.dirname(__file__))
sys.path = ['/opt/gridops/usage/temp'] + sys.path
os.chdir(os.path.dirname(__file__))
sys.stdout = sys.stderr
import bottle
print "++"*10
import index # This loads your application
application = bottle.default_app()
index.py
:
from bottle import mount, run
from routes import app
from bottle import default_app
default_app.push(app)
#run()
#run(app=app, host='192.168.1.3', port=8085)
routes.py
:
from bottle import Bottle , run,route,static_file,view,template,post,request
app = Bottle()
print str(dir(app))
@app.route('/static/<filename>')
def server_static(filename):
return static_file(filename, root='static')
@app.route('/')
def index():
return template('template',text='This is index page!')
template.tpl
:
<html>
<head>
<link rel="stylesheet" type="text/css" href="static/prettify.css" />
</head>
<body>
{{text}}
</body>
</html>
目录列表
temp/
adapter.wsgi
index.py
routes.py
static/
prettify.css
views/
template.tpl
我的问题是每当我尝试使用以下方式访问 Bottle 应用程序时 http://192.168.1.3/temp
网页显示没有静态文件,但每当我访问 http://192.168.1.3/temp/
[请注意额外 /
] 页面加载正确。我应该做什么修改才能使两者的结果http://192.168.1.3/temp
和 http://192.168.1.3/temp/
变得一样?
任何帮助都会非常有帮助
解决方案
问题
有问题的一行是这一行:
<link rel="stylesheet" type="text/css" href="static/prettify.css" />
CSS 文件的地址是相对地址,因此完整的绝对地址是根据加载的页面位置计算的。
为了 http://192.168.1.3/temp/
, , 这将是 http://192.168.1.3/temp/static/prettify.css
(正确的)。
为了 http://192.168.1.3/temp
, , 这将是 http://192.168.1.3/static/prettify.css
. temp
被认为是根目录中的文件,而不是其本身的子目录。
解决方案
没有可行的方法来使用单个相对地址来引用静态资源。您的应用程序可能会有“嵌套”路径,例如 /article/some-name
, , 或者 /view/content/566
, ,或类似的东西,以及简单的路径 /
.
您可以尝试指定基于根的路径,例如 /temp/static/prettify.css
, ,在您的模板中,但这意味着如果您重新定位应用程序本身(例如, myapp.example.com/
从 example.com/myapp/
).
相反,您需要告诉框架为您需要使用的资源创建正确的路径。Bottle 有一个名为 获取网址 以促进这一点。不幸的是,Bottle 教程中没有提到这一点。
代码
这是你应该做的。
在 template.tpl
, , 称呼 get_url
引用静态处理程序:
<link rel="stylesheet" type="text/css"
href="{{ get_url('static', filename='prettify.css') }}" />
在 routes.py
, , 进口 get_url
:
from bottle import Bottle, run, route, static_file, view, template,
post, request, get_url
然后,命名您的处理程序,以便您可以将其名称传递给 get_url
:
@app.route('/static/<filename>', name='static')
def server_static(filename):
return static_file(filename, root='static')
最后提供实际情况 get_url
作为渲染模板时的模板参数:
@app.route('/')
def index():
return template('template', text='This is index page!', get_url=get_url)
或者,不提供 get_url
在每个处理程序中,设置模板默认值 index.py
:
from Bottle import SimpleTemplate
SimpleTemplate.defaults["get_url"] = app.get_url
警告:最后一个方法似乎没有记录,但是 Bottle 的作者在邮件列表中进行了解释.
最后的想法
由于网站上的每个页面都应该有一个规范地址,因此您可能需要选择一种形式(带尾部斜杠或不带斜杠)作为规范,并从另一种形式添加某种重定向。
其他提示
另一种解决方法是在 Apache 配置文件中添加此重定向:
RedirectMatch 301 ^/(temp)$ /$1/
这将在索引页末尾添加一个 /,因此您不必修改代码。
一种解决方法是添加:
<base href="/temp/">
到模板中的头部。