Google App Engine静态文件服务与应用程序冲突

时间:2014-03-10 04:00:23

标签: python google-app-engine

我有一个单页应用程序(SPA),我正在运行Google App Engine(GAE)。 GAE做了三件事:

  1. 提供index.html文件
  2. 提供静态文件(JS,CSS等)
  3. 通过REST提供动态文件(图像,文本等)
  4. 我使用以下app.yaml配置。

    handlers:
    - url: /app
      static_dir: app
    
    - url: /.*
      script: main.app
    

    我的理解是,这应该匹配任何进入/ app文件夹的请求,这将提供我的静态文件。然后,所有REST服务和主索引页都将被/.*捕获并由main.py

    处理

    但是,我看到以下行为:

    1. 如果我删除/ app处理程序,我可以成功地提供index.html(通过Jinja模板)和REST服务(例如localhost / subjects /)。 然而,我看不到静态文件(正如预期的那样)。
    2. 如果我添加/ app处理程序,则index.html文件不会投放并提供"内部服务器错误" IOError(错误.EACCES,'文件无法访问',文件名)。 但是,当我请求静态文件时,例如:" localhost / app / app.js",这会成功。
    3. 我在这里缺少一些东西吗?我不明白为什么两者会发生冲突。

      谢谢!

      注意: Google App Engine 1.8.9,Python 2.7,本地开发

      修改

      以下是我用来提供页面的Python代码

      path = os.path.join(os.path.dirname(__file__), 'app')
      jinja_environment = jinja2.Environment(loader=jinja2.FileSystemLoader(path))
      
      class MainHandler(webapp2.RequestHandler):
        def get(self):
          self.response.headers['Content-Type'] = 'text/html'
          template_values = {}
          template = jinja_environment.get_template('index.html')
          self.response.out.write(template.render(template_values))
      

      我的目录结构如下:

      /

      • main.py

      • app.yaml&等

      • 应用

        • 的index.html

        • app.js

        • 模块A

        • moduleA.tpl.html

        • moduleA.js

      编辑2:

      我将index.html移动到根目录(/),然后使用以下python代码:

      path = os.path.dirname(__file__)
      jinja_environment = jinja2.Environment(loader=jinja2.FileSystemLoader(path))
      

      它(非常有趣的是)出现了"双重映射" index.html对Jinja模板和静态目录文件造成了问题。我想知道这样做的最佳做法是什么。我使用Jinja的原因之一是:将(GAE生成的)登录/注销链接添加到index.html文件中。除此之外,没有理由使用它。

3 个答案:

答案 0 :(得分:3)

默认情况下,Python无法访问App Engine中标记为静态的文件或目录。您可以将application_readable: true添加到处理程序映射中以启用此功能。

另一个解决方案是将index.html移离静态文件夹,因为它实际上不是静态文件,而是Python的jinja模板。

  

application_readable

     

可选。默认情况下,在静态文件处理程序中声明的文件作为静态数据上载,并且仅提供给最终用户,应用程序无法读取它们。如果此字段设置为true,则文件也会作为代码数据上载,以便您的应用程序可以读取它们。这两个上传都是针对您的代码和静态数据存储资源配额收取的。

答案 1 :(得分:1)

好吧它可能解释了场景#2,你如何访问index.html?如果您将/ app添加到处理程序,并且您的请求网址类似于/app/index.html,则它将从静态目录中提供。

在您的方案中,您的网址似乎不包含/ app,因此它会转到第二个处理程序规则,该规则将转到main.app。

但是,由于您将html放在/ app中,因此appengine将其视为静态文件。如果您想从jinja模板提供文件,则不应将其放在static_dir

答案 2 :(得分:0)

Jinja模板(或Django,Mako等)无需位于可公开访问的文件夹中。它们总是通过应用程序中的处理程序调用,并在提供给用户之前在应用程序中编译。

通常将它们放在/ templates目录中。 app.yaml中没有对此目录的引用,它纯粹在内部用于提供模板。查看github中的一些样板应用程序(搜索' gae样板')。这个是最小的并且使用Jinja,所以对你来说可能是一个很好的例子https://github.com/SoulAuctioneer/notvanillae