Разница между `cherrypy.InternalRedirect` и` cherrypy.HTTPRedirect`? - PullRequest
0 голосов
/ 21 апреля 2020

Я изучил код следующим образом в веб-разработке Cherrypy,

if returnpage != '':
   raise cherrypy.InternalRedirect(returnpage)
else:
   raise cherrypy.HTTPRedirect("/hqc")

Google не сильно помогает в этом случае после того, как я провел некоторое исследование. Я проверял у вишни __doc__, но документация там очень краткая.

>>>print(cherrypy.InternalRedirect.__doc__)
Exception raised to switch to the handler for a different URL.

    This exception will redirect processing to another path within the site
    (without informing the client). Provide the new path as an argument when
    raising the exception. Provide any params in the querystring for the new URL.

>>> print(cherrypy.HTTPRedirect.__doc__)
Exception raised when the request should be redirected.

    This exception will force a HTTP redirect to the URL or URL's you give it.
    The new URL must be passed as the first argument to the Exception,
    e.g., HTTPRedirect(newUrl). Multiple URLs are allowed in a list.
    If a URL is absolute, it will be used as-is. If it is relative, it is
    assumed to be relative to the current cherrypy.request.path_info.

    If one of the provided URL is a unicode object, it will be encoded
    using the default encoding or the one passed in parameter.

    There are multiple types of redirect, from which you can select via the
    ``status`` argument. If you do not provide a ``status`` arg, it defaults to
    303 (or 302 if responding with HTTP/1.0).

    Examples::

        raise cherrypy.HTTPRedirect("")
        raise cherrypy.HTTPRedirect("/abs/path", 307)
        raise cherrypy.HTTPRedirect(["path1", "path2?a=1&b=2"], 301)

    See :ref:`redirectingpost` for additional caveats.

Мои вопросы: - Зачем беспокоиться о перенаправлении, когда вы можете просто вызвать другой обработчик? - Что такое практический сенар ios для двух исключений перенаправления соответственно?

1 Ответ

1 голос
/ 21 апреля 2020

InternalRedirect обрабатывается только на стороне сервера, это означает, что клиент не будет знать об этом перенаправлении, потому что с точки зрения протокола HTTP, который является посредником сеанса между клиентом и сервером, ничего не изменилось. Под серверной стороной я подразумеваю, что ТОЛЬКО CherryPy будет осведомлен о перенаправлении, если у вас есть какой-нибудь промежуточный сервер (например, nginx обратный прокси), он не увидит ничего другого.

Например, если клиент посетил URL /page_one, а затем вы использовали raise InternalRedirect('/page_two'), клиент (браузер) получит содержимое от обработчика /page_two в URL /page_one. Если вы подняли обычный HTTPRedirect, сервер завершит первый запрос с кодом состояния HTTP 303 (или любым другим состоянием, которое вы передали исключению) и заголовком Location для /page_two. Затем клиент будет инициировать еще один запрос к /page_two, в основном все будут осведомлены о перенаправлении ( больше информации о перенаправлении HTTP ). В большинстве случаев это лучшая альтернатива.

Кроме того, вы можете определить, поступил ли запрос от предыдущего InternalRedirect, проверив свойство cherrypy.request.prev. В качестве значения он будет иметь предыдущий объект cherrypy.request или None.

Ради возможного (может быть, не лучшего примера) использования InternalRedirect, ознакомьтесь с этой страницей примера производства / беты. Кроме того, я добавил инструмент, запрещающий клиенту напрямую обращаться к обработчикам.

Клиент увидит другой контент на той же странице /. Обратите внимание, что журнал доступа, который генерирует CherryPy, будет регистрировать URL-адрес обработчика, который в конечном итоге обработает запрос, в этом случае вы увидите /_beta или /_production.

import random
import cherrypy


@cherrypy.tools.register('before_handler')
def private_handler():
    """End the request with HTTP 404 not found if the client
    tries to reach the handler directly instead of being
    internally redirected from other handler.
    """
    if cherrypy.request.prev is None:
        raise cherrypy.NotFound()


class MainApp:

    @cherrypy.expose
    def index(self):
        # 50/50 change of receiving production or the new SHINY beta page
        use_beta = random.randint(0, 1)
        if use_beta:
            raise cherrypy.InternalRedirect('/_beta')
        else:
            raise cherrypy.InternalRedirect('/_production')

    @cherrypy.tools.private_handler()
    @cherrypy.expose
    def _production(self):
        return (
            "<html>"
            "<h2>{}</h2>"
            "</html>"
        ).format(
            "Welcome to our awesome site!"
        )

    @cherrypy.tools.private_handler()
    @cherrypy.expose
    def _beta(self):
        return (
            "<html>"
            '<h1 style="color: blue">{}</h1>'
            "<p>{}</p>"
            "</html>"
        ).format(
            "Welcome to our awesome site!",
            "Here is our new beta content..."
        )


cherrypy.quickstart(MainApp())
...