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