简体   繁体   English

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

[英]Google App Engine static file serving conflicts with application

I have a single page app (SPA) that I am running off of Google App Engine (GAE). 我有一个单页应用程序(SPA),我正在使用Google App Engine(GAE)。 GAE does three things: GAE做三件事:

  1. Serve the index.html file 服务index.html文件
  2. Serve the static files (JS, CSS, etc.) 服务静态文件(JS,CSS等)
  3. Serve the dynamic files (images, text, etc. via REST) 通过REST服务动态文件(图像,文本等)

I use the following app.yaml configuration. 我使用以下app.yaml配置。

handlers:
- url: /app
  static_dir: app

- url: /.*
  script: main.app

My understanding is that this should match any requests going to the /app folder, which would serve my static files. 我的理解是,这应该匹配到/ app文件夹的所有请求,该请求将为我的静态文件提供服务。 All the REST services and the main index page would then be caught by the /.* and processed by main.py 然后,所有的REST服务和主索引页面将被/.*捕获并由main.py处理

However, I see the following behavior: 但是,我看到以下行为:

  1. If I remove the /app handler, I can successfully serve the index.html (via Jinja templating) and the REST services (such as localhost/subjects/). 如果删除/ app处理程序,则可以成功提供index.html(通过Jinja模板)和REST服务(例如localhost / subjects /)。 However , I cannot see the static files (as expected). 但是 ,我看不到静态文件(按预期)。
  2. If I add the /app handler, the index.html file does not serve and gives an "Internal Server Error" IOError(errno.EACCES, 'file not accessible', filename). 如果添加/ app处理程序,则index.html文件将提供服务,并给出“内部服务器错误” IOError(errno.EACCES,“文件不可访问”,文件名)。 However , when I request a static file such as: "localhost/app/app.js", this succeeds. 但是 ,当我请求诸如“ localhost / app / app.js”之类的静态文件时,此操作成功。

Is there something that I am missing here? 我在这里缺少什么吗? I do not understand why the two would conflict. 我不明白为什么两者会发生冲突。

Thank you! 谢谢!

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

EDIT: 编辑:

Here is the Python code I am using to serve the page 这是我用来提供页面的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))

My directory structure is as follows: 我的目录结构如下:

/ /

  • main.py main.py

  • app.yaml & etc. app.yaml等

  • app 应用

    • index.html 的index.html

    • app.js app.js

    • Module A 模块A

    • moduleA.tpl.html moduleA.tpl.html

    • moduleA.js moduleA.js

Edit 2: 编辑2:

I moved index.html to the root directory (/), and then used the following python code: 我将index.html移到根目录(/),然后使用以下python代码:

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

It (very interestingly) appears that the "double mapping" of the index.html to the Jinja template and to the static directory files caused a problem. (非常有趣)似乎是index.html到Jinja模板以及静态目录文件的“双重映射”引起了问题。 I wonder what is the best practice way to do this. 我想知道什么是最佳做法。 I use Jinja for one reason: adding the (GAE generated) login/logout link to the index.html file. 我使用Jinja的原因是:将(GAE生成的)登录/注销链接添加到index.html文件。 Other than that, there is no reason for using it. 除此之外,没有理由使用它。

Python is by default unable to access files or directories marked as static in App Engine. 默认情况下,Python无法访问App Engine中标记为静态的文件或目录。 You can add application_readable: true to your handler mapping to enable this. 您可以在处理程序映射中添加application_readable: true以启用此功能。

Another solution would be to move the index.html away from the static folder since it in fact isn't a static file but instead is a jinja template for Python. 另一个解决方案是将index.html从静态文件夹中移开,因为它实际上不是静态文件,而是Python的Jinja模板。

application_readable application_readable

Optional. 可选的。 By default, files declared in static file handlers are uploaded as static data and are only served to end users, they cannot be read by an application. 默认情况下,在静态文件处理程序中声明的文件将作为静态数据上传,并且仅提供给最终用户,应用程序无法读取它们。 If this field is set to true, the files are also uploaded as code data so your application can read them. 如果此字段设置为true,则文件也将作为代码数据上传,因此您的应用程序可以读取它们。 Both uploads are charged against your code and static data storage resource quotas. 两次上载均按您的代码和静态数据存储资源配额收费。

Ok it might explains scenario #2, how do you access the index.html? 好的,它可以解释方案#2,如何访问index.html? If you add /app to the handler and your request url is something like /app/index.html it will serve from the static dir. 如果将/ app添加到处理程序中,并且您的请求网址类似于/app/index.html,则它将从静态目录中提供。

On your scenario seems your url does not contain /app, therefore it goes to the 2nd handler rule which is going to main.app. 在您的情况下,您的网址似乎不包含/ app,因此转到第二个处理程序规则,该规则将进入main.app。

However since you put the html inside the /app, appengine treats it as static file. 但是,由于您将html放在/ app内,因此appengine将其视为静态文件。 If you want to serve the file from jinja template, you should not put it in static_dir 如果要通过jinja模板提供文件,则不应将其放在static_dir中

Jinja templates (or Django, Mako etc) has no requirement to be sat in a publicly accessible folder. Jinja模板(或Django,Mako等)无需位于公共可访问的文件夹中。 They are always called via a handler in the application and compiled in the application before serving to the user. 它们始终通过应用程序中的处理程序进行调用,并在服务给用户之前在应用程序中进行编译。

It is common practice to put these in a /templates directory. 通常将它们放在/ templates目录中。 There is no reference to this directory in app.yaml, it is purely used internally to serve the templates. app.yaml中没有对该目录的引用,它仅在内部用于提供模板。 Check out some of the boilerplate apps in github (search 'gae boilerplate'). 在github中查看一些样板应用程序(搜索“ gae样板”)。 This one is minimal and uses Jinja so may be a good example for you https://github.com/SoulAuctioneer/notvanillae 这是最小的并且使用Jinja,所以可能是您的一个很好的例子https://github.com/SoulAuctioneer/notvanillae

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

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