App Engine 为除根以外的任何路径抛出 404 Not Found

App Engine throws 404 Not Found for any path but root

我想将我的 App Engine 实现拆分成几个文件。所以我在我的 app.yaml 文件中写道:

runtime: python27
api_version: 1
threadsafe: true

handlers:

- url: /imageuploader
  script: imageuploader.app

- url: /search
  script: main.app

- url: /
  static_files: index.html
  upload: index.html

libraries:
- name: MySQLdb
  version: "latest"

基本上我搜索和图片上传是在不同的路径和根路径上有索引文件。

这是我的处理人员:

main.py:

class MainPage(webapp2.RequestHandler):

    def get(self):
        #Implementation

app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

imageuploader.py:

class UserPhoto(ndb.Model):
    blob_key = ndb.BlobKeyProperty()


class PhotoUploadFormHandler(webapp2.RequestHandler):
    def get(self):
        # [START upload_url]
        upload_url = blobstore.create_upload_url('/upload_photo')
        # [END upload_url]
        # [START upload_form]
        # To upload files to the blobstore, the request method must be "POST"
        # and enctype must be set to "multipart/form-data".
        self.response.out.write("""
<html><body>
<form action="{0}" method="POST" enctype="multipart/form-data">
  Upload File: <input type="file" name="file"><br>
  <input type="submit" name="submit" value="Submit">
</form>
</body></html>""".format(upload_url))
        # [END upload_form]


# [START upload_handler]
class PhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        try:
            upload = self.get_uploads()[0]
            user_photo = UserPhoto(
                user=users.get_current_user().user_id(),
                blob_key=upload.key())
            user_photo.put()

            self.redirect('/view_photo/%s' % upload.key())

        except:
            self.error(500)
# [END upload_handler]


# [START download_handler]
class ViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, photo_key):
        if not blobstore.get(photo_key):
            self.error(404)
        else:
            self.send_blob(photo_key)
# [END download_handler]


app = webapp2.WSGIApplication([
    ('/', PhotoUploadFormHandler),
    ('/upload_photo', PhotoUploadHandler),
    ('/view_photo/([^/]+)?', ViewPhotoHandler),
], debug=True)
# [END all]

现在,奇怪的是,如果我设置

-url: /.*
    script: main.app

一切正常。我还尝试了 /search/.+/imageuploader/.+。我一定是忘记了一些非常明显的东西,但我想不出来是什么。

每个 app.yaml 路由脚本配置(如 script: imageuploader.app)需要一个具有匹配名称(imageuploader.py 在这种情况下)的 python 文件,它定义了一个名为app(就像 main.py 一样)应用程序路由当然是(或等于)app.yaml 文件(/imageuploader 中的相应路径的子集这种情况)。

因此,您的实施存在问题:

  • main.py 应用程序路径是 / - 与 app.yaml
  • 中对应的 /search 路径不匹配 imageuploader.py 中的 3 个应用程序路径模式中的
  • none 与 app.yaml
  • 中相应的 /imageuploader 路径匹配
  • app.yaml 中的 / 路径实际上映射到静态资源 index.html,因此它将直接由 GAE 提供服务 - 没有必要为其添加处理程序永远不应调用处理程序(您可能需要重新访问静态资源映射)。

您使用 /.* 映射到 main.app 的尝试只能在 之前 您现在在 imageuploader.py 中删除处理程序代码之前起作用,但应该未使用您问题中的 main.py 内容。

假设 app.yaml 中的模式是您想要的模式,这些将是您需要的应​​用程序配置(继续您的方法):

main.py:

app = webapp2.WSGIApplication([
    ('/search', MainPage),
], debug=True)

imageuploader.py:

app = webapp2.WSGIApplication([
    ('/imageuploader', ...),  # TODO: revisit mappings
], debug=True)

但我建议使用处理程序代码的 webapp2's lazy loading 更简单的管理方法。

您在 app.yaml 中保留了一个单一的通用映射,它将匹配 任何 url 模式 main.py 文件中:

- url: /.*
  script: main.app

您在 main.py 中只有一个应用程序路由映射定义,但它可以从 main.py 和其他 modules/files 中延迟加载处理程序。例如这样的事情:

app = webapp2.WSGIApplication([    
    ('/upload', 'imageuploader.PhotoUploadFormHandler'),
    ('/upload_photo', 'imageuploader.PhotoUploadHandler'),
    ('/view_photo/([^/]+)?', 'imageuploader.ViewPhotoHandler'),
    ('/main_page', MainPage),
], debug=True)

中间方法也是可能的,允许您将 imageuploader.pymain.py 完全分离,但稍微更谨慎 url 模式选择。

你可以在 app.yaml:

- url: /photo.*
  script: imageuploader.app

并且在 imageuploader.py 中有 url 模式匹配 /photo.* 一个:

app = webapp2.WSGIApplication([
    ('/photo_upload_form', PhotoUploadFormHandler),
    ('/photo_upload', PhotoUploadHandler),
    ('/photo_view/([^/]+)?', ViewPhotoHandler),
], debug=True)