Google App Engine 静态页面 Python 2.5 目录等
我刚开始接触这个,打算把我的东西从一个付费的网络服务迁移到GAE(只是静态页面,没有动态内容)。相信我,我花了无数个小时试图让这个工作,但现在遇到了瓶颈,我总是只能实现一个结果,而另一个结果就无法实现,反之亦然。
我相信这个问题的答案很简单,我可能违反了一些基本原则。我想要的是,应用引擎页面(mygaeid.appspot.com)能提供一个静态的首页,同时其他页面可以通过添加后缀来访问,比如 mygaeid.appspot.com/oranges.html、mygaeid.appspot.com/grapes.html 等等。
我无法做到这一点,要么我能在添加后缀后访问其他页面,比如 mygaeid.appspot.com/apples.html、mygaeid.appspot.com/oranges.html,但首页却无法访问;要么我稍微修改一下yaml文件,首页(mygaeid.appspot.com)可以正常工作,但无法访问带有后缀的其他页面(mygaeid.appspot.com/oranges.html 等等)。
下面是py文件(abcdefg.py),它在接下来的两个不同的yaml文件中是通用的:
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
class MainHandler(webapp.RequestHandler):
def get (self, q):
if q is None:
q = 'htmdir/apples.html'
path = os.path.join (os.path.dirname (__file__), q)
self.response.headers ['Content-Type'] = 'text/html'
self.response.out.write (template.render (path, {}))
def main ():
application = webapp.WSGIApplication ([('/(.*html)?', MainHandler)], debug=True)
util.run_wsgi_app (application)
if __name__ == '__main__':
main ()
使用下面的yaml,首页(mygaeid.appspot.com)可以完美工作(显示apples.html的内容),但我无法在添加后缀后访问页面,比如 mygaeid.appspot.com/apples.html 或 mygaeid.appspot.com/static/htmdir/apples.html 等等,一旦我添加后缀就无法工作。在目录(htmdir)中,我放置了apples.html和其他html页面,比如oranges.html等,但使用这个yaml我无法访问任何页面。
application: mygaeid
version: 1
runtime: python
api_version: 1
handlers:
- url: /(.*\.(html))
static_files: static/htmdir/\1
upload: static/htmdir/(.*\.(html))
- url: /css
static_dir: css
- url: /js
static_dir: js
- url: /images
static_dir: images
- url: .*
script: abcdefg.py
如果我按照以下方式修改yaml,那么首页(mygaeid.appspot.com)就无法工作,但当我添加后缀时,它就能完美工作,比如 mygaeid.appspot.com/apples.html;mygaeid.appspot.com/oranges.html 等等都能正常显示相应的页面:
- url: /(.*\.(html))
static_files: htmdir/\1
upload: htmdir/(.*\.(html))
最后,如果我完全不使用目录,并且使用相同的abcdefg.py(没有目录),那么以下这个非常简单的yaml实际上能实现我想要的结果,但所有文件都堆在根目录下,这样就显得很乱。
application: mygaeid
version: 1
runtime: python
api_version: 1
handlers:
- url: /(.*\.(png|js|css))
static_files: \1
upload: (.*\.(png|js|css))
- url: .*
script: abcedfg.py
如果能帮我解决这个问题,我将非常感激。谢谢!
谢谢wooble,也谢谢dave,我又回去仔细查看了日志。Wooble的解决方案有效,但我需要把包含html的htmdir放在一个叫做static的目录里。GAE是一个很棒(而且免费的)静态网站解决方案。
非常感谢你们的帮助和反馈。
SiteDirectory
-mygaeid
-static
-htmdir
-js
-css
-images
app.yaml
index.yaml
(py file was removed)
3 个回答
这样工作的原因是有技术上的考虑
app.yaml 配置文件的工作方式非常简单,就是从上到下按顺序执行。
匹配的顺序如下:
1. - url: /(.*\.(html))
static_files: static/htmdir/\1
upload: static/htmdir/(.*\.(html))
2. - url: /css
static_dir: css
3. - url: /js
static_dir: js
4. - url: /images
static_dir: images
5. - url: .*
script: abcdefg.py
简单来说,如果文件后缀是 .html,那么在第一步就会被匹配,并把请求从 mygaeid.appspot.com/.html 转到 mygaeid.appspot.com/htmdir/.html。第五步的 *.html 处理程序不会被触发,因为所有的 *.html 路径已经被占用了。
另外,正如其他回答所提到的,标记为静态的目录在你的应用处理程序中是无法本地访问的。我会尝试解释一下技术原因。
app.yaml 作为 GAE 的反向代理配置文件。静态文件只有在上传时才会改变,所以它们非常适合缓存。通过在部署时立即将静态文件推送到缓存服务器,GAE 提高了加载性能,并减少了应用服务器的负担。
静态请求被单独计算,并且费用比普通应用请求低是有原因的。每次你请求一个静态文件,实际上就是从 GAE 的 CDN 拉取这个文件。如果你只请求静态文件,那么你的服务器根本就没有启动的必要。
这种方法的明显缺点是,这些文件并不在和你的应用同一个服务器上,所以你不能直接在应用中获取或上传它们。
注意:也遵循了其他回答的内容。不要把你的模板文件夹标记为静态。当你的应用加载模板时——而不是从相邻目录获取——它会发送一个网络请求,从远程位置获取文件。显然,从远程获取文件而不是本地文件会增加加载时间和延迟。
Woobie的回答是对的。让我换个说法。
当你把.html文件放在static_files
里时,这些文件会由专门处理静态内容的服务来提供。你的应用程序是看不到这些文件的。应用程序只能看到被称为资源的文件。
Django的模板必须是资源,而不是静态文件。否则,应用程序就无法找到它们,template.render(path, ...
这个命令就会出错。
解决你问题的下一步是(如果你还没做的话)更新你的帖子,展示一下你当前的app.yaml
文件,并告诉我们应用程序日志中报告了什么。
如果你在app.yaml文件中把某些文件声明为静态文件,那么这些文件就不能被你的应用程序处理了。
不过,如果这些文件确实是静态的,使用django模板引擎去“渲染”它们就有点多余了;你只需要在app.yaml中添加一些映射,就可以直接显示这些静态文件,比如可以为根目录(/)显示apples.html:
application: mygaeid
version: 1
runtime: python
api_version: 1
handlers:
- url: /(.*\.html)
static_files: static/htmdir/\1
upload: static/htmdir/.*\.html
- url: /css
static_dir: css
- url: /js
static_dir: js
- url: /images
static_dir: images
- url: /
static_files: static/htmdir/apples.html
upload: static/htmdir/apples\.html
(不需要任何python文件)