Python Google应用程序引擎静态文件服务与应用程序冲突

Python Google应用程序引擎静态文件服务与应用程序冲突,python,google-app-engine,Python,Google App Engine,我有一个单页应用程序(SPA),我正在运行谷歌应用程序引擎(GAE)。GAE做三件事: 提供index.html文件 提供静态文件(JS、CSS等) 通过REST提供动态文件(图像、文本等) 我使用以下app.yaml配置 handlers: - url: /app static_dir: app - url: /.* script: main.app 我的理解是,这应该匹配到/app文件夹的任何请求,该文件夹将为我的静态文件提供服务。所有REST服务和主索引页都将被/*捕获并由ma

我有一个单页应用程序(SPA),我正在运行谷歌应用程序引擎(GAE)。GAE做三件事:

  • 提供index.html文件
  • 提供静态文件(JS、CSS等)
  • 通过REST提供动态文件(图像、文本等)
  • 我使用以下app.yaml配置

    handlers:
    - url: /app
      static_dir: app
    
    - url: /.*
      script: main.app
    
    我的理解是,这应该匹配到/app文件夹的任何请求,该文件夹将为我的静态文件提供服务。所有REST服务和主索引页都将被/*捕获并由main.py处理

    但是,我看到以下行为:

  • 如果删除/app处理程序,我可以成功地为index.html(通过Jinja模板)和REST服务(例如localhost/subjects/)提供服务但是,我无法看到静态文件(如预期的那样)
  • 如果添加/app处理程序,index.html文件将不起作用,并给出一个“内部服务器错误”IOError(errno.EACCES,“文件不可访问”,文件名)但是,当我请求一个静态文件,例如:“localhost/app/app.js”,这会成功
  • 这里有我遗漏的东西吗?我不明白为何两者会发生冲突

    谢谢大家!

    注: 谷歌应用引擎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

    • 应用程序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文件。除此之外,没有理由使用它。

    好的,这可能解释了场景2,如何访问index.html?如果您将/app添加到处理程序中,并且您的请求url类似于/app/index.html,那么它将从静态目录提供服务

    在您的场景中,您的url似乎不包含/app,因此它将转到main.app的第二个处理程序规则


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

    好的,这可能解释了场景2,如何访问index.html?如果您将/app添加到处理程序中,并且您的请求url类似于/app/index.html,那么它将从静态目录提供服务

    在您的场景中,您的url似乎不包含/app,因此它将转到main.app的第二个处理程序规则


    但是,由于您将html放在/app中,appengine将其视为静态文件。如果您希望从jinja模板提供文件,则不应将其放入静态目录中。默认情况下,Python无法访问在App Engine中标记为静态的文件或目录。您可以将
    应用程序\u readable:true
    添加到处理程序映射以启用此功能

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

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


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

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

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

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

    通常的做法是将它们放在/templates目录中。app.yaml中没有对该目录的引用,它仅在内部用于提供模板。查看github中的一些样板应用程序(搜索“gae样板”)。这一个是最小的,并且使用了Jinja,因此可能是一个很好的例子

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


    通常的做法是将它们放在/templates目录中。app.yaml中没有对该目录的引用,它仅在内部用于提供模板。查看github中的一些样板应用程序(搜索“gae样板”)。这一个是最小的,使用了Jinja,因此可能是一个很好的示例

    您将index.html放在哪里?似乎是您将index.html放在了导致问题的/app中。@mar