Google App Engine和404错误

我已经使用在其他地方发现的提示在GAE上设置了一个静态网站,但无法弄清楚如何返回一个404错误。 我的app.yaml文件看起来像

- url: (.*)/ static_files: static\1/index.html upload: static/index.html - url: / static_dir: static 

所有的静态HTML / JPG文件存储在静态目录下。 上面的工作对于存在的文件,但是如果不存在则返回一个空长文件。 答案可能是编写一个python脚本来返回一个404错误,但是如何设置这些脚本来为存在的静态文件提供服务,但是如果文件没有运行脚本,该怎么办呢?

以下是从开发应用程序服务器上获取不存在的文件(nosuch.html)的日志:

 ERROR 2008-11-25 20:08:34,084 dev_appserver.py] Error encountered reading file "/usr/home/ctuffli/www/tufflinet/static/nosuch.html": [Errno 2] No such file or directory: '/usr/home/ctuffli/www/tufflinet/static/nosuch.html' INFO 2008-11-25 20:08:34,088 dev_appserver.py] "GET /nosuch.html HTTP/1.1" 404 - 

你需要注册一个catch-all脚本处理程序。 在app.yaml的末尾追加这个:

 - url: /.* script: main.py 

在main.py中,你将需要把这个代码:

 from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app class NotFoundPageHandler(webapp.RequestHandler): def get(self): self.error(404) self.response.out.write('<Your 404 error html page>') application = webapp.WSGIApplication([('/.*', NotFoundPageHandler)], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main() 

用有意义的东西replace<Your 404 error html page> 。 或者更好的使用一个模板,你可以在这里阅读如何做到这一点 。

如果您在设置时遇到问题,请告诉我。

谷歌应用程序引擎现在有自定义错误响应

所以你现在可以在你的app.yaml中添加一个error_handlers部分,如下例所示:

 error_handlers: - file: default_error.html - error_code: over_quota file: over_quota.html 

在不需要任何CPU周期的情况下,更简单的方法是将此处理程序放在app.yaml的底部

 - url: /.* static_files: views/404.html upload: views/404.html 

这就允许你在你的视图目录中放置一个静态的404.html文件。 不需要python处理程序。 任何不在你的app.yaml中处理的东西已经打到了。

您可以创build一个函数来处理任何状态码的错误。 你的情况是404,定义一个这样的函数:

 def Handle404(request, response, exception): response.out.write("Your error message") response.set_status(404)` 

您可以在response.out.write函数中传递任何内容 – HTML /纯文本/模板。 现在,在您的app声明之后添加以下声明。

app.error_handlers[404] = Handle404

这对我有效。

webapp2提供了error_handlers字典,您可以使用它来提供自定义错误页面。 示例如下:

 def handle_404(request, response, exception): logging.warn(str(exception)) response.set_status(404) h = YourAppBaseHandler(request, response) h.render_template('notfound') def handle_500(request, response, exception): logging.error(str(exception)) response.set_status(500) h = YourAppBaseHandler(request, response) h.render_template('servererror') app = webapp2.WSGIApplication([ webapp2.Route('/', MainHandler, name='home') ], debug=True) app.error_handlers[404] = handle_404 app.error_handlers[500] = handle_500 

有关webapp2文档页面的更多详细信息,请访问: http : webapp2

dev_appserver已经为任何不匹配的映射返回404响应,或者映射不匹配,但不存在。 404响应本身没有内容,但仍然是404:

 $ wget -O - http://127.0.0.1:8080/foo --2010-10-28 10:54:51-- http://127.0.0.1:8080/foo Connecting to 127.0.0.1:8080... connected. HTTP request sent, awaiting response... 404 2010-10-28 10:54:51 ERROR 404: (no description). $ wget -O - http://127.0.0.1:8080/foo/ --2010-10-28 10:54:54-- http://127.0.0.1:8080/foo/ Connecting to 127.0.0.1:8080... connected. HTTP request sent, awaiting response... 404 2010-10-28 10:54:54 ERROR 404: (no description). 

如果你想返回一个更友好的错误页面,请按照jonmiddleton的build议,并指定一个自定义404页面。

我已经回顾了上面给出的所有答案,并在最后使用了最通用的404解决scheme:

app.yaml的最后添加这个链接

 - url: /(.*) script: 404.app 

并使用以下内容创build404.py

 import webapp2 from google.appengine.ext.webapp import template class NotFound(webapp2.RequestHandler): def get(self): self.error(404) self.response.out.write(template.render('404.html', {})) app = webapp2.WSGIApplication([ ('/.*', NotFound) ], debug=True) 

这将显示404错误代码的404.html文件的内容。

这个解决scheme的优点是简单,正确的bahaviour和灵活性,因为它允许使用静态404.html文件作为错误页面内容。

我也想警告一些上面build议的解决scheme。

  • Custom Error Responses不适用于404错误
  • 也不要使用静态文件,因为它们会返回200而不是404错误。 这可能会导致很多头痛。

我不能评论jonmiddleton的答案,但自定义的错误响应是由App的引擎特定的错误的外观。 我没有看到指定自定义404页面的方法。

Django让你指定一个。

我的方法是处理404和永久redirect在一个捕获所有处理程序,我把最后一个。 这是有用的,当我重新devise和应用程序和重命名/replaceurl:

 app = webapp2.WSGIApplication([ ... ... ('/.*', ErrorsHandler) ], debug=True) class ErrorsHandler(webapp2.RequestHandler): def get(self): p = self.request.path_qs if p in ['/index.html', 'resources-that-I-removed']: return self.redirect('/and-substituted-with-this', permanent=True) else: self.error(404) template = jinja_environment.get_template('404.html') context = { 'page_title': '404', } self.response.out.write(template.render(context))