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