Подтвердить что ты не робот

Ошибка 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 script, чтобы вернуть ошибку 404, но как вы устанавливаете вещи для обслуживания статических файлов, которые существуют, но запускают script для файлов, которые этого не делают?

Вот журнал из выборки несуществующего файла (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 -
4b9b3361

Ответ 1

Вам необходимо зарегистрировать обработчик catch-all script. Добавьте это в конец вашего 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()

Замените <Your 404 error html page> чем-то значимым. Или лучше использовать шаблон, вы можете прочитать, как это сделать здесь.

Пожалуйста, дайте мне знать, если у вас возникли проблемы с настройкой.

Ответ 2

В Google App Engine теперь есть Пользовательские ответы об ошибках

чтобы теперь вы могли добавить раздел error_handlers в свой app.yaml, как в этом примере:

error_handlers:

- file: default_error.html

- error_code: over_quota
    file: over_quota.html

Ответ 3

Значительно простой способ сделать это, не требуя каких-либо циклов процессора, - разместить этот обработчик в нижней части вашего app.yaml

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

Затем вы можете поместить статический файл 404.html в каталог представлений. Нет необходимости в обработчике python. Все, что не обрабатывается в вашем app.yaml, уже ударит по этому.

Ответ 4

Вы можете создать функцию для обработки ваших ошибок для любого из кодов состояния. Вы делаете 404, определите такую ​​функцию:

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

Вы можете передать что угодно - HTML/plain-text/templates в функции response.out.write. Теперь добавьте следующее объявление после объявления app.

app.error_handlers[404] = Handle404

Это сработало для меня.

Ответ 5

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://webapp-improved.appspot.com/guide/app.html#error-handlers

Ответ 6

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 и укажите пользовательскую страницу 404.

Ответ 7

Я рассмотрел все приведенные выше ответы и использовал в конце в качестве наиболее универсального решения 404:

Добавьте эту ссылку в конец app.yaml

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

и создайте 404.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.html с кодом ошибки 404.

Преимуществом этого решения является простота, правильность работы и гибкость, поскольку он позволяет использовать статический файл 404.html в качестве содержимого страницы ошибки.

Я также хочу предупредить о некоторых из предложенных выше решений.

  • Custom Error Responses не работает с ошибкой 404
  • Также не используйте статические файлы, так как они возвращают 200 вместо ошибки 404. Это может вызвать много головной боли.

Ответ 8

Я не могу комментировать ответ jonmiddleton, но пользовательские ответы об ошибках относятся к конкретным ошибкам App Engine по внешнему виду. Я не вижу способа указать пользовательскую страницу 404.

Django позволяет вам указать один.

Ответ 9

Мой подход заключается в том, чтобы обрабатывать как 404, так и постоянные переадресации в обработчике catch, который я ставил как последний. Это полезно, когда я редизайна и приложение и переименовываю/заменяю URL:

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))