简体   繁体   English

省略尾部斜杠时,未在Bottle应用程序中加载静态文件

[英]Static files not loaded in a Bottle application when the trailing slash is omitted

I am serving a test file through apache using Bottle. 我正在使用Bottle通过apache提供测试文件。

Following are my apache config: 以下是我的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 : 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 : 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 : 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 : template.tpl

<html>
<head>

<link rel="stylesheet" type="text/css" href="static/prettify.css" />
</head>
<body>
{{text}}
</body>

</html>

Directory Listing 目录列表

temp/
  adapter.wsgi
  index.py
  routes.py
  static/
     prettify.css
  views/
     template.tpl

My issue is whenever I try to access the Bottle app using http://192.168.1.3/temp the webpage shows up without the static files, but whenever i access http://192.168.1.3/temp/ [Please note the extra / ] the page loads properly. 我的问题是每当我尝试使用http://192.168.1.3/temp访问Bottle应用程序时,网页显示没有静态文件,但每当我访问http://192.168.1.3/temp/ [请注意额外/ ]页面正确加载。 What modification should I do such that the result of both http://192.168.1.3/temp and http://192.168.1.3/temp/ become the same? 我应该做什么修改,使得http://192.168.1.3/temphttp://192.168.1.3/temp/的结果变得相同?

Any help would be highly helpful 任何帮助都会非常有帮助

The Problem 问题

The problematic line is this one: 问题是这一行:

<link rel="stylesheet" type="text/css" href="static/prettify.css" />

The address of the CSS file is a relative one, thus the full absolute address is computed from the loaded page location. CSS文件的地址是相对的,因此从加载的页面位置计算完整的绝对地址。

For http://192.168.1.3/temp/ , it will be http://192.168.1.3/temp/static/prettify.css (correct). 对于http://192.168.1.3/temp/ ,它将是http://192.168.1.3/temp/static/prettify.css (正确)。

For http://192.168.1.3/temp , it will be http://192.168.1.3/static/prettify.css . 对于http://192.168.1.3/temp ,它将是http://192.168.1.3/static/prettify.css temp is considered to be a file in the root directory, not a subdirectory of its own right. temp被认为是根目录中的文件,而不是它自己的子目录。

The Solution 解决方案

There is no viable way to use a single relative address for referring to the static resources. 没有可行的方法来使用单个相对地址来引用静态资源。 Your application will likely to have “nested” paths like /article/some-name , or /view/content/566 , or something like this, as well as paths as simple as / . 您的应用程序可能具有“嵌套”路径,例如/article/some-name/view/content/566 ,或类似的东西,以及像/一样简单的路径。

You can try to specify a root-based path, like /temp/static/prettify.css , in your template, but this means you will have to change the template if you relocate the app itself (say, to myapp.example.com/ from example.com/myapp/ ). 您可以尝试在模板中指定基于根的路径,例如/temp/static/prettify.css ,但这意味着如果您重新定位应用程序本身,则必须更改模板(例如,更改为myapp.example.com/来自example.com/myapp/ )。

Instead, you need to tell the framework to make the correct path to the resource you need to use. 相反,您需要告诉框架为您需要使用的资源建立正确的路径。 Bottle has a function named get_url to facilitate this. Bottle有一个名为get_url的函数来促进这一点。 Unfortunately, it's not mentioned in the Bottle tutorials. 不幸的是,瓶子教程中没有提到它。

The Code 编码

Here's what you should do. 这是你应该做的。

In template.tpl , call get_url referring to the static handler: template.tpl ,调用get_url引用静态处理程序:

<link rel="stylesheet" type="text/css" 
      href="{{ get_url('static', filename='prettify.css') }}" />

In routes.py , import get_url : routes.py ,进口get_url

from bottle import Bottle, run, route, static_file, view, template, 
                   post, request, get_url

Then, name your handler so you can pass its name to get_url : 然后,为您的处理程序命名,以便将其名称传递给get_url

@app.route('/static/<filename>', name='static')
def server_static(filename):
    return static_file(filename, root='static')

Finally, supply the actual get_url as the template argument when rendering the template: 最后,在渲染模板时提供实际的get_url作为模板参数:

@app.route('/') 
def index(): 
    return template('template', text='This is index page!', get_url=get_url)

Alternatively, instead of supplying get_url in every handler, set up a template default in index.py : 或者,而不是提供get_url在每一个处理程序,成立了一个模板默认index.py

from Bottle import SimpleTemplate
SimpleTemplate.defaults["get_url"] = app.get_url

Caveat : The last method seems to be undocumented, but was explained by the Bottle's author on the mailing list . 警告 :最后一种方法似乎没有记录,但是由邮件列表上的Bottle的作者解释

Final Thought 最后的想法

As every page on a website should have a canonical address, you might want to choose one form (either with a trailing slash or without one) as canonical, and add some kind of redirect from the other one. 由于网站上的每个页面都应该具有规范地址,因此您可能希望选择一个表单(带有斜杠或没有斜杠)作为规范,并从另一个表单添加某种重定向。

Another workaround is to add this redirection in your Apache configuration file : 另一种解决方法是在Apache配置文件中添加此重定向:

RedirectMatch 301 ^/(temp)$ /$1/

This will add a / at the end of your index page, so you don't have to modify your code. 这将在索引页的末尾添加一个/,因此您不必修改代码。

One workaround is to add: 一种解决方法是添加:

<base href="/temp/">

to the head in the template. 到模板的头部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM