【问题标题】:Bottle Static files瓶静态文件
【发布时间】:2012-05-16 04:55:50
【问题描述】:

我已经尝试阅读 Bottle 的文档,但是,我仍然不确定静态文件服务的工作原理。我有一个index.tpl 文件,其中有一个附加的css文件,它可以工作。但是,我读到 Bottle 不会自动提供 css 文件,如果页面加载正确,这是不可能的。

但是,我在请求页面时遇到了速度问题。那是因为我没有使用return static_file(params go here)吗?如果有人能弄清楚它们是如何工作的,以及在加载页面时如何使用它们,那就太好了。

服务器代码:

from Bottle import route,run,template,request,static_file



@route('/')
def home():
    return template('Templates/index',name=request.environ.get('REMOTE_ADDR'))

run(host='Work-PC',port=9999,debug=True)

索引:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="content-type"
 content="text/html; charset=ISO-8859-1">
  <title>index</title>
  <link type="text/css"
 href="cssfiles/mainpagecss.css"
 rel="stylesheet">
</head>
<body>
<table
 style="width: 100%; text-align: left; margin-left: auto; margin-right: auto;"
 border="0" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <td>
      <h1><span class="headertext">
      <center>Network
Website</center>
      </span></h1>
      </td>
    </tr>
  </tbody>
</table>
%if name!='none':
    <p align="right">signed in as: {{name}}</p>
%else:
    pass
%end
<br>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2"
 cellspacing="2">
  <tbody>
    <tr>
      <td>
      <table style="text-align: left; width: 100%;" border="0"
 cellpadding="2" cellspacing="2">
        <tbody>
          <tr>
            <td style="width: 15%; vertical-align: top;">
            <table style="text-align: left; width: 100%;" border="1"
 cellpadding="2" cellspacing="2">
              <tbody>
                <tr>
                  <td>Home<br>
                  <span class="important">Teamspeak Download</span><br>
                  <span class="important">Teamspeak Information</span></td>
                </tr>
              </tbody>
            </table>
            </td>
            <td style="vertical-align: top;">
            <table style="text-align: left; width: 100%;" border="1"
 cellpadding="2" cellspacing="2">
              <tbody>
                <tr>
                  <td>
                  <h1><span style="font-weight: bold;">Network Website</span></h1>
To find all of the needed information relating to the network's social
capabilities, please refer to the links in the side bar.</td>
                </tr>
              </tbody>
            </table>
            </td>
          </tr>
        </tbody>
      </table>
      </td>
    </tr>
  </tbody>
</table>
</body>
</html>

【问题讨论】:

  • 我对bottle了解不多,但是说它不提供静态文件的说法可能仅适用于生产模式,不适用于开发。让您的 Apache 或您正在使用的任何东西提供静态文件通常会更有效。顺便说一句......你的 HTML 中有太多的表格;)

标签: python python-2.7 bottle


【解决方案1】:

要使用bottle 提供静态文件,您需要使用提供的static_file 函数并添加一些额外的路由。以下路由引导静态文件请求并确保仅访问具有正确文件扩展名的文件。

from bottle import get, static_file

# Static Routes
@get("/static/css/<filepath:re:.*\.css>")
def css(filepath):
    return static_file(filepath, root="static/css")

@get("/static/font/<filepath:re:.*\.(eot|otf|svg|ttf|woff|woff2?)>")
def font(filepath):
    return static_file(filepath, root="static/font")

@get("/static/img/<filepath:re:.*\.(jpg|png|gif|ico|svg)>")
def img(filepath):
    return static_file(filepath, root="static/img")

@get("/static/js/<filepath:re:.*\.js>")
def js(filepath):
    return static_file(filepath, root="static/js")

现在在您的 html 中,您可以像这样引用文件:

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

目录布局:

`--static
|  `--css
|  `--fonts
|  `--img
|  `--js

【讨论】:

  • 包含# Static Routes 的模块的名称是什么,它位于项目目录的什么位置?
  • 我在项目目录的根目录中有一个server.py 文件,该文件运行服务器并包含静态路由,而静态目录也只是在项目目录的根目录中。跨度>
  • 使用&lt;:re:.*/&gt;&lt;filename:re:.*\.js&gt;以便some/path/some.jssome.js工作
  • @SankethKatta 有一个循环类型,额外的右括号:return static_file(filepath, root="static/img") here>>)
  • 我不得不将所有的 '@get' 更改为 '@route',否则,您的示例解决了我的问题。
【解决方案2】:

这里只是提供一个答案,因为我的一些学生在作业中使用了此代码,我对解决方案有点担心。

在 Bottle 中提供静态文件的标准方式是在 documentation

from bottle import static_file
@route('/static/<filepath:path>')
def server_static(filepath):
    return static_file(filepath, root='/path/to/your/static/files')

这样,静态文件夹下的所有文件都从以 /static 开头的 URL 提供。在您的 HTML 中,您需要引用资源的完整 URL 路径,例如:

&lt;link rel='stylesheet' type='text/css' href='/static/css/style.css'&gt;

来自 Sanketh 的回答使得对 URL 空间中任何位置的图像、css 文件等的任何引用都从静态文件夹内的给定文件夹提供。所以 /foo/bar/baz/picture.jpg 和 /picture.jpg 都将从 static/images/picture.jpg 提供。这意味着您无需担心在 HTML 代码中获取正确的路径,并且您始终可以使用相对文件名(即,只需 src="picture.jpg")。

当您尝试部署应用程序时,就会出现这种方法的问题。在生产环境中,您希望静态资源由像 nginx 这样的 Web 服务器提供服务,而不是由您的 Bottle 应用程序提供服务。为了实现这一点,它们都应该从 URL 空间的单个部分提供,例如。 /静止的。如果您的代码中充斥着相关文件名,则它不会轻易转换为该模型。

因此,我建议使用 Bottle 教程中的三行解决方案,而不是本页列出的更复杂的解决方案。它是更简单的代码(因此不太可能出现错误),它允许您无缝迁移到生产环境而无需更改代码。

【讨论】:

  • 几年前我写了我的原始答案,当时我的项目使参考文件变得更好,就像我为我的用例所做的那样。我已经更新了答案,使其更符合本教程,并且可以很好地用于生产部署。但是,我保留了每种文件类型的单独路由,以额外检查每个文件夹中允许的文件扩展名。
【解决方案3】:

如文档中所述,您应该使用 static 函数提供静态文件,而 css 是一个静态文件。静态函数处理安全性和您可以从源代码中找到的其他一些函数。静态函数的 path 参数应该指向存储 css 文件的目录

【讨论】:

  • 那么我应该如何设置它以使用我的模板?或者这只是在部署到生产服务器而不是开发服务器时。服务器?
  • Bottle 有一个名为 TEMPLATE_PATH 的变量,它是 Bottle 搜索模板的路径列表。检查bottle.py 源文件中的第2839 行。您可以使用默认路径之一,也可以将正在使用的路径添加到该列表中。
  • 所以如果我将模板路径添加到该变量,然后使用return static_file(pathtomycss) 那我应该怎么做?如果没有,你能给我举个例子吗?我对所有这些问题感到抱歉,我刚刚开始在 web 开发 x.x
  • 否..您可以将 html 模板 文件的路径添加到模板路径,但 css 文件通常包含在不同的文件夹中。您将该文件夹的路径传递给 static_file 函数。
  • 所以我有两个返回函数?模板和静态文件?
【解决方案4】:

而不是像 Sanketh 的回答那样使用正则表达式匹配来提供文件,我宁愿不修改我的模板并明确提供静态文件的路径,如下所示:

<script src="{{ get_url('static', filename='js/bootstrap.min.js') }}"></script>

您只需将静态路由装饰器中的 &lt;filename&gt; 替换为 :path 类型之一即可完成此操作 - 如下所示:

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

:path 以非贪婪的方式匹配整个文件路径,因此您不必担心切换到生产时更改模板 - 只需将所有内容保持在相同的相对文件夹结构中。

【讨论】:

  • 注意:在本例中,我在模板中使用get_url,但您也可以轻松地手动指定链接 - /static/js/bootstrap.min.js
【解决方案5】:

我过去曾使用过 Sanketh 的模板,但随着时间的推移,我将其浓缩为与扩展无关的功能。您只需在 ext_map 字典中添加扩展文件夹映射。如果未明确映射扩展名,则默认为 static/ 文件夹。

import os.path    

# Static Routes
@get('/<filename>')
def serve_static_file(filename):
    ext = os.path.splitext(filename)[1][1:]
    ext_map = {'image':['png','gif','jpg','ico'],'js':['js']}
    sub_folder = next((k for k, v in ext_map.items() if ext in v),'')
    return static_file(filename, root='static/'+sub_folder)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多